2

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!

1

3 Answers 3

6

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

Sign up to request clarification or add additional context in comments.

Comments

2

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

1 Comment

Somebody know how to use Stream<QuerySnapshot> in a obs variable with GetX the proper way?
2

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());
  },
);

3 Comments

@Kamlesh You'd need to use rxdart package which I myself didn't try yet.
Thanks dear @CopsOnRoad, I have already used it, but may be something missing or not working yet.
@Kamlesh Unfortunately I can't help you much in that. Sorry :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.