EsotericLanguage
EsotericLanguage

Reputation: 149

how to retrieve specific data from Cloud Firestore using flutter and dart?

I have been all over StackOverflow reading-related posts. However, I have yet to find one with a simple solution easy for a beginner such as myself to understand. Currently, my Cloud Firestore database looks like the following:

My Cloud Firestore database layout

after the user has entered enough information to populate each of the fields in a document (ID is UID of an authenticated user via phone auth) then it gets sent into the database. Afterward, the user is redirected to the home screen where each of these fields should be displayed. This is where I am stuck. Below is a method I have started to implement that will return a string that will be inside a Text widget to display the username found inside the database.

String getUsername(FirebaseUser user, Firestore firestore) {

    //get the document reference
    DocumentReference docReference = firestore.document("Users/" + user.uid);

    Future<DocumentSnapshot> snapshot = docReference.get();

    Stream<DocumentSnapshot> stream = snapshot.asStream();

    //stub to ignore compiler warnings
    return null;
 }

As you can see I'm fairly lost when it comes to using Futures and Streams. I have watched the videos on youtube by google flutter developers and they have helped me get up to this point. I also tried playing around with the then() and whenCompleted() methods offered by Future objects however I found myself digging a bigger and bigger hole.

All help is very much appreciated!

Upvotes: 2

Views: 7777

Answers (3)

CopsOnRoad
CopsOnRoad

Reputation: 267404

The following code is null safe and has been updated to latest versions of libraries:

var collection = FirebaseFirestore.instance.collection('users');
  
FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
  future: collection.doc('${user.uid}').get(),
  builder: (_, snapshot) {
    if (snapshot.hasError) return Text('Error = ${snapshot.error}');
  
    if (snapshot.hasData) {
      var output = snapshot.data!.data();
      var value = output!['email']; // [email protected]
      return Text(value);
    }
  
    return Center(child: CircularProgressIndicator());
  },
);

Upvotes: 2

Peter Haddad
Peter Haddad

Reputation: 80904

To get the user info try the following:

Future<DocumentSnapshot> getUserInfo()async{
var firebaseUser = await FirebaseAuth.instance.currentUser();
return await Firestore.instance.collection("users").document(firebaseUser.uid).get();
}

Then use FutureBuilder in your build() method:

          FutureBuilder(
            future: getUserInfo(),
            builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                return ListView.builder(
                    shrinkWrap: true,
                    itemCount: 1,
                    itemBuilder: (BuildContext context, int index) {
                      return ListTile(
                        title:
                            Text(snapshot.data.data["email"]),
                      );
                    });
              } else if (snapshot.connectionState == ConnectionState.none) {
                return Text("No data");
              }
              return CircularProgressIndicator();
            },
          ),

When using await inside a method, then that method needs to be declared async. Also you need to return a Future, to be able to display the result in the screen, then you need to use the FutureBuilder widget.

https://dart.dev/codelabs/async-await

Upvotes: 6

Gonzalo Gauto
Gonzalo Gauto

Reputation: 181

When you need to fetch data only once you can use Futures for example:

final queryofdocs = await Firestore.instance.collection('Users').getDocuments()

this code returns a Future<QuerySnapshot> with all the documents in that collection. Then you can try fetch one document like this:

final queryofonedocs = await Firestore.instance.document('users/uid').get()

This return a Future<DocumentSnapshot> with all fields in that document.

For last you can listen to data changes with Streams.

final suscription = await Firestore.instance.collection('tasks').snapshots()

This return a Stream<QuerySnapshot> , if you change some data un firestore the data in the app updates.

DocumentSnapshots have the info fields on a document and QuerySnapshot is a collection of DocumentSnapshots.

Hope it helps

Upvotes: 2

Related Questions