Returns null during reading data from firebase? - flutter

I am fetching data of a collection from firebase and it returns null. It works if I change the collection name but then again it shows the above problem.

You are doing the wrong code formate
Please follow below code formate for right response
if (snapshot.hasError) {
return Container(child:Text("error"),);
}
else if(snapshot.hasData){
return
.....
your widget listview
.....
} else{
return Center(child: circularProgress(),);
}

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

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.

Getting a field value from known document in firebase 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');
},
),

Is there any method to show loading widget while retrieving data from Firebase Realtime Database in flutter

Here is snippet of code for loading data from firebase realtime database to a list:
var CategoryName = FirebaseDatabase.instance.reference().child('CategoryNames').once()
.then((DataSnapshot dataSnapshot){
var key = dataSnapshot.value.keys;
for(var i in key)
{
// print(dataSnapshot.value[i]['Name']);
CategoriesOnly categoriesOnly = new CategoriesOnly(
dataSnapshot.value[i]['Name']
);
categoriesOnlyList.add(categoriesOnly);
}
setState(() {
print(categoryItemList.length);
});
});
I'm storing these data into a list and showing them into ListView.builder.
And I want to show the screen once data is fully loaded meanwhile it show some kind of loading widget or loading screen but in my case screen looks blank and after sometime it shows the data. And if internet connectivity is slow blank screen appears for a minutes and loads it(because my data contains images as well). And also I want if loading time exceeds from some specific time it will show try reloading again or internet connectivity error. Please help.
As the other people already said I think the best solution would be a FutureBuilder like this:
FutureBuilder(
future: //your future you want the data from,
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text("None");
case ConnectionState.active:
return Text("active");
case ConnectionState.waiting: /while you are waiting for the data...
return CupertinoActivityIndicator(); //thats the typical apple loading
return CircularProgressIndicator(); // this would be a blue circle
case ConnectionState.done:
//you have the data and can access it with 'snapshot.data'
}
}),