What is the difference between existing types of snapshots in Firebase?
As far as I can tell you are asking this in the context of Flutter, so I'll answer for that below.
There are two databases in Firebase: the original Realtime Database, and the newer Cloud Firestore. Both are equally valid options today, but they are completely separate with their own API. But both return snapshots of data, where the snapshot is a copy of the data from the database in your application code.
In Flutter you have FutureBuilder
and StreamBuilder
, which deal with snapshots of data that is loaded asynchronously.
Let's see if I can cover them:
- An AsyncSnapshot is Flutter's wrappers around data from asynchronous data sources, such as Firestore and Realtime Database. They cover the states that such data can be in, from the initial connection, through retrieval, until errors or having the data.
-
DocumentSnapshots and QuerySnapshots are Firestore's classes to either represent a single document, or a list of documents that you get when reading from the database. So if you load a single document, you get a
DocumentSnapshot
with its data. And if you load a list of document, you get aQuerySnapshot
that you then loop over to access the individualDocumentSnapshot
s. - A DataSnapshot is the Realtime Database's class for both a single Node, and a list of nodes from the database.
So in Flutter you'll have an AsyncSnapshot
that refers to one of the Firebase snapshot classes, and that Firebase snapshot then wraps the actual data.
Say you want to display a list with the documents in a collection from Firestore, you'll have:
- An
AsyncSnapshot
to feed to yourStreamBuilder
, so that it can render the correct state of data loading. - A
QuerySnapshot
for the list of documents from the database. - Each item in that list is then a
DocumentSnapshot
with a snapshot of the data from a single document.
I actually find this much easier to see in code, as in this example from the FlutterFire documentation:
class UserInformation extends StatelessWidget {
@override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return StreamBuilder<QuerySnapshot>(
stream: users.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return new ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document.data()['full_name']),
subtitle: new Text(document.data()['company']),
);
}).toList(),
);
},
);
}
}