I used this code bevor migration
StreamBuilder(
stream: FirebaseDatabase.instance
.ref()
.child('user')
.child(_userID)
.onValue,
builder: (context, snapshot) {
if (snapshot.hasData) {
_networkImageUrl = snapshot.data.snapshot.value["img"];
return Text(_networkImageUrl.toString());
} else {
return Container();
}
}),
after "dart pub upgrade --null-safety" I get the error:
The property 'snapshot' can't be unconditionally accessed because the receiver can be 'null'.
I tried to fix it with "!" but it doesn't work, it keeps the same error
this is the code:
StreamBuilder<DatabaseEvent>(
stream: FirebaseDatabase.instance
.ref()
.child('user')
.child(_userID)
.onValue,
builder: (BuildContext context,AsyncSnapshot snapshot) {
if (snapshot.hasData) {
Map<dynamic, dynamic> userDocument = snapshot.data.snapshot.value;
_networkImageUrl = userDocument["img"]
return Text(_networkImageUrl.toString());
} else {
return Container();
}
}),
Thanks to #h8moss
Related
Flutter Streambuilder code below runs without error and returns (screenshot at bottom):
ID: AzFdOO9WsFaFbTxTQsuo
Data: Instance of '_JsonDocumentSnapshot'
How do I get to the values inside the _JsonDocumentSnapshot and display them in the Text() widget?
For instance, there's a string field called "name", but I can't figure out how to get to it.
StreamBuilder(
stream: FirebaseFirestore.instance
.collection("groceries")
.doc(widget.docId)
.snapshots(),
builder: (context, streamSnapshot) {
if (streamSnapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
} else if (streamSnapshot.hasData) {
return Text("ID: ${widget.docId}\n"
"Data: ${streamSnapshot.data}");
} else {
return const Text("No Data");
}
}
)
Thanks for your help!
the following Stream, return an object with a type of DocumentSnapshot :
FirebaseFirestore.instance.collection("groceries").doc(widget.docId).snapshots();
and that type contains the document snapshot, and also contains more additional information about the document.
so in order to get the JSON Map<String, dynamic> which represents the data of the Firestore document, you need to call data() on the result of the snapshot.data(), so you need to try the following:
StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection("groceries")
.doc(widget.docId)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> streamSnapshot) {
if (streamSnapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
} else if (streamSnapshot.hasData) {
return Text("ID: ${widget.docId}\n"
"Data: ${streamSnapshot.data.data()}"); // added data()
} else {
return const Text("No Data");
}
}
)
now it should show the Map<String, dynamic> object which contains your document data in the Text widget.
hope this helps.
In your code example streamSnapshot.data is an Object or a dynamic type variable.
To access the json value of your data, you have to specify the key corresponding to your value.
streamSnapshot.data['banana']
I have a StreamBuilder to check for an empty string But I want to turn it to check for an empty array. How can I do that?
bool? checkEmpty = false;
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('widgets')
.doc(widgets)
.snapshots(),
builder: (context, snapshot) {
snapshot.data?.data()?.forEach((key, value) {
if (key == 'imageUrl') {
checkEmpty = value == [];
}
});
return ...
checkEmpty!
? Text('Array is not empty')
: Text('Empty array'),
cast the value type as List then check over it.
try the following:
bool? checkEmpty = false;
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('widgets')
.doc(widgets)
.snapshots(),
builder: (context, snapshot) {
snapshot.data?.data()?.forEach((key, value) {
if (key == 'imageUrl') {
checkEmpty = (value as List).isEmpty;
}
});
return ...
checkEmpty!
? Text('Array is not empty')
: Text('Empty array'),
I'm expecting my random value to be an int but I got a String instead,
is this the right way to do it.
StreamBuilder(
stream: FirebaseDatabase.instance.ref().child('RandomVal').onValue,
builder: (context, snapshot) {
if (snapshot.hasData && !snapshot.hasError) {
final event = snapshot.data as DatabaseEvent;
final data = event.snapshot.value as Map;
print(data['Value']); // my value as expected
print(data['Value'].runtimeType); // String instead of int
}
return Text('please wait');
},
),
I try to count all docs from one user in firestore.
My code:
Widget booksWidget(String userData) {
return
StreamBuilder(
stream: FirebaseFirestore.instance
.collection("bookList")
.doc(userData)
.collection(userData)
.orderBy("timestamp", descending: true)
.snapshots(),
builder: (BuildContext context,AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var userDocument = snapshot.data as DocumentSnapshot?;
String books = userDocument?.length.toString();
return Text(books);
}else{
return Text("none");
}
}
);
}
the error:
The getter 'length' isn't defined for the type 'DocumentSnapshot<Object?>'.
thanks for help, streambuilder after migration to null-safety is quite different :(
You're requesting the snapshots of a query, so the snapshot.data that you get is going to be of type QuerySnapshot (and not a DocumentSnapshot? as you assume now).
if (snapshot.hasData) {
var querySnapshot = snapshot.data! as QuerySnapshot;
String books = querySnapshot.docs.length.toString();
...
In cases like this I find it easiest to work from the reference documentation, such as the one for Query.snapshots() here.
List<Photo> imgList = [];
Future getCarouselWidget() async {
var firestore = Firestore.instance;
QuerySnapshot qn =
await firestore.collection("history").getDocuments();
List pics = qn.documents
.map((it) => Photo(it['photo'].toString(), it['name'].toString(), it['address'].toString()))
.toList();
return imgList = pics;
}
Hi all, when I make changes in my DB I dont see them in my app? can anybody help me or guid me how to wire this to stream builder or query the stream
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection('swimfinderlakes')
.snapshots(),
builder: (context, snapshot) {
Every time Firestore has a change, it'll trigger the StreamBuilder. U can then access the most recently update with the snapshot on the builder method. Then you can use it to update the ui accordingly.
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection('swimfinderlakes')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.hasData) {
List pics = qn.documents
.map((it) => Photo(it['photo'].toString(),
it['name'].toString(), it['address'].toString())).toList();
return pics;
}
} else {
return CircularProgressIndicator();
}
}