Getting a field value from known document in firebase flutter - flutter

I want a user to give a value in my app and other user to see it. But i can upload data to firebase but not get it on the other side. I have null safety enabled on flutter. The code is :-
child: StreamBuilder(
stream:FirebaseFirestore.instance.collection('Collection name').doc('doc id').snapshots()
builder: (context, snapshot){
if(snapshot.hasData){
return Text(snapshot.data['Field name'].toString()); // here my editor shows error saying 'The method '[]' can't be unconditionally invoked because the receiver can be 'null'.' and asks for a null check and then shows error again
}
return Text('Nothing');
}
),
Edit: I am getting only 'type '_JsonDocumentSnapshot' is not a subtype of type 'Map<String, dynamic>' in type cast' as the error
And if I change
if(snapshot.hasData){
return Text(snapshot.data['Field name'].toString());
to
if (snapshot.hasData) {
return Text(snapshot.data.toString());
}
i get output as
'Instance of '_JsonDocumentSnapshot''
where the data should be.
I am using null check dart

Thannks for everyone's support, but i have accidently found and answer. I read that the data type of that is DocumentSnapshot and this worked for me
builder: (context, snapshot) {
if (snapshot.hasData) {
var numGuess = snapshot.data as DocumentSnapshot;
return Text(numGuess['Field name'].toString());
}
return Text('Nothing');
}
This works for null safety.

Since you are retrieving a collection then try the following:
return Text(snapshot.data!.docs[0].data()["Field Name"]);
A collection will return a list of documents, therefore use the docs property to be able to access the document. The above code will show the field in the first document in the list, it's better if you use a listview to return all documents.
Check:
https://api.flutter.dev/flutter/widgets/ListView-class.html

Give datatype to your StreamBuilder like this
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream:
FirebaseFirestore.instance.collection('Collection name').doc('doc id').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data?.data()?['Field name']);
}
return Text('Nothing');
},
),

Related

Issue in firestore database

I want to show current user data in my flutter app. But it print on screen " No data found".
This my database data
That error also happened error
My security rule
enter image description here
Here is my code
Container(
child: StreamBuilder(
stream: FirebaseFirestore.instance.collection("user3").where("id",isEqualTo:FirebaseAuth.instance.currentUser!.uid).snapshots(),
builder: (BuildContext context,AsyncSnapshot<QuerySnapshot> snapshot){
if(!snapshot.hasData){
return Text("Loading please wait........");
}
if (snapshot.hasData && snapshot.data!.docs.length > 0) {
DocumentSnapshot userData = snapshot.data!.docs[0];
// Build the widget using the userData
} else {
return Center(child: Text("No data found"));
}
return Container();
},
),
),
The long numeric values (e.g. "167582...") in your database screenshot do not look like a UID that any of the Firebase Authentication providers would generate.
Add this code right before you query the database:
print(FirebaseAuth.instance.currentUser!.uid)
This will show you the value that you're querying for, which (given my opening statement) probably looks quite different from the value in your database.
If that is indeed the case, the problem starts when you write the document. At that point you'll want to make sure that you write the value of FirebaseAuth.instance.currentUser!.uid to the id field.

How to set the object variable permanently in Flutter?

I am trying to build an app with Flutter and Dart. Here, I want to retrieve data from my Firebase, and I was able to do so and put it in the replies variable in each Message object that I have as an array type in the Firebase by using a for loop. However, when I try to access the replies variable again, it becomes empty.
I tried using setState, but that just causes the replies variable to keep resetting. Why this is the case, and how can I fix it?
StreamBuilder<List<Message>> pickMessage(
Stream<List<Message>> list, BuildContext context) {
return StreamBuilder(
stream: list,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong!');
} else if (snapshot.hasData) {
final message = snapshot.data!;
for (var msg in message) {
FirebaseFirestore.instance.collection("messages").doc(msg.msgID).get().then((value){
msg.replies = value.get("replies");
});
}
If You Need Some Variable to Initialize Once Put in Init Function or In Builder Function, outside the Scope of StreamBuilder, hope it helps

How to display a list from database in flutter

I am a beginner in flutter, I want to retrieve a list of announcements from the database and display it in a listView but I have a compilation error under snapshot.data saying that A value of type 'List<Annonce>?' can't be assigned to a variable of type 'List<Annonce>'. Try changing the type of the variable, or casting the right-hand type to 'List<Annonce>'.
The code is :
future: AnnonceDataBase.instance.annonces(),
builder: (BuildContext context,
AsyncSnapshot<List<Annonce>> snapshot) {
if (snapshot.hasData) {
List<Annonce> annonces = snapshot.data;
return ListView.separated(... ```
Change like this:
future: AnnonceDataBase.instance.annonces(),
builder: (BuildContext context,
AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Annonce> annonces = snapshot.data! as List<Annonce>;
return ListView.separated(... ```
Oh, by the way, Please consider to vote up and give it as accepted answer if an answer solves your problem. The reason is that other people with same issue can easily find the right answer easily. Have fun!

Null check operator used on a null value (error)

This is the code:
​// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables
​import​ ​'package:cloud_firestore/cloud_firestore.dart'​;
​import​ ​'package:firebase_auth/firebase_auth.dart'​;
​import​ ​'package:flutter/material.dart'​;
​import​ ​'package:google_nav_bar/google_nav_bar.dart'​;
​import​ ​'package:projectciplified/screens/read%20data/get_user_name.dart'​;
​class​ ​HomePage​ ​extends​ ​StatefulWidget​ {
​  ​const​ ​HomePage​({​Key​?​ key}) ​:​ ​super​(key​:​ key);
​  ​#override
​  ​State<​HomePage​>​ ​createState​() ​=>​ ​_HomePageState​();
​}
​class​ ​_HomePageState​ ​extends​ ​State<​HomePage​>​ {
​  ​final​ user ​=​ ​FirebaseAuth​.instance.currentUser​!​;
​  ​//document ids
​  ​List<​String​>​ docIDs ​=​ [];
​  ​// method to get document ids
​  ​Future​ ​getDocID​() ​async​ {
​    ​await​ ​FirebaseFirestore​.instance.​collection​(​'users'​).​get​().​then​(
​          (snapshot) ​=>​ snapshot.docs.​forEach​(
​            (document) {
​              ​print​(document.reference);
​              docIDs.​add​(document.reference.id);
​            },
​          ),
​        );
​  }
​  ​#override
​  ​Widget​ ​build​(​BuildContext​ context) {
​    ​return​ ​Scaffold​(
​      appBar​:​ ​AppBar​(
​        title​:​ ​Text​(
​          user.email​!​,
​          style​:​ ​TextStyle​(fontSize​:​ ​16​),
​        ),
​        actions​:​ [
​          ​GestureDetector​(
​              onTap​:​ () {
​                ​FirebaseAuth​.instance.​signOut​();
​              },
​              child​:​ ​Icon​(​Icons​.logout)),
​        ],
​      ),
​      bottomNavigationBar​:​ ​Container​(
​        color​:​ ​Colors​.black,
​        child​:​ ​Padding​(
​          padding​:​ ​const​ ​EdgeInsets​.​symmetric​(
​            horizontal​:​ ​15​,
​            vertical​:​ ​20.0​,
​          ),
​          child​:​ ​GNav​(
​            backgroundColor​:​ ​Colors​.black,
​            color​:​ ​Colors​.white,
​            activeColor​:​ ​Colors​.white,
​            tabBackgroundColor​:​ ​Colors​.blue,
​            padding​:​ ​EdgeInsets​.​all​(​10​),
​            gap​:​ ​2​,
​            onTabChange​:​ (index) {},
​            tabs​:​ [
​              ​GButton​(
​                icon​:​ ​Icons​.home,
​                text​:​ ​'Home'​,
​              ),
​              ​GButton​(
​                icon​:​ ​Icons​.favorite_border,
​                text​:​ ​'likes'​,
​              ),
​              ​GButton​(
​                icon​:​ ​Icons​.search,
​                text​:​ ​'search'​,
​              ),
​              ​GButton​(
​                icon​:​ ​Icons​.settings,
​                text​:​ ​'settings'​,
​              ),
​            ],
​          ),
​        ),
​      ),
​      body​:​ ​Center​(
​        child​:​ ​Column​(
​          mainAxisAlignment​:​ ​MainAxisAlignment​.center,
​          children​:​ [
​            ​Expanded​(
​                child​:​ ​FutureBuilder​(
​              future​:​ ​getDocID​(),
​              builder​:​ (context, snapshot) {
​                ​return​ ​ListView​.​builder​(
​                  itemCount​:​ docIDs.length,
​                  itemBuilder​:​ (context, index) {
​                    ​return​ ​Padding​(
​                      padding​:​ ​const​ ​EdgeInsets​.​all​(​8.0​),
​                      child​:​ ​ListTile​(
​                        tileColor​:​ ​Colors​.grey[​200​],
​                        title​:​ ​GetUserName​(documentID​:​ docIDs[index]),
​                      ),
​                    );
​                  },
​                );
​              },
​            )),
​          ],
​        ),
​      ),
​    );
​  }
​}
I'm trying to get the user info with ​FirebaseAuth​.instance.currentUser! but it's giving said error.
With ​FirebaseAuth​.instance.currentUser (without the !) The code works but why?
Can someone explain the null error? I'm not sure why this code doesn't work as it worked around 5 hours ago. How do I fix it? Thanks for your help.
There are few states FutureBuilder provides, like connection state, error state and data or empty state. While you calling future it needs some time to fetch data, means first state is loading state and data is not ready yet. That's why it says null error because we don't have any data.
Do like
FutureBuilder(
future: ​getDocID​(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (snapshot.hasData) {
return ListView(...);
}
else return Text("dont have any data")
},
Find more about FutureBuilder on flutter.dev.

How to properly use future builder inside a column

Hello i'm using a future builder inside my column widget( i have other widgets sadly ).
Here is my code :
FutureBuilder(
future: loadStudent(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return (snapshot.data.student)
.map<Widget>((std) => StudentProfile(
std.StudentName,
std.StudentPicture,
std.speciality,
std.badge))
.toList();
} else {
return CircularProgressIndicator();
}
}),
well it throws this error:
type 'List' is not a subtype of type 'Widget'.
I understand what the error mean ( basicly column takes individual widgets as children ) , yet i don't know how to fix it .
Please note that i tried to use the '...' operator in my return statement it threw another error :
Expected an identifier, but got '...'
You are returning a List of Widget instead of a Widget.
You need to put your List on a Column Widget like this :
List students = (snapshot.data.student)
.map<Widget>((std) => StudentProfile(
std.StudentName,
std.StudentPicture,
std.speciality,
std.badge)).toList();
return Column(
children: students,
)