Alex Ali
Alex Ali

Reputation: 1369

Flutter: Firestore Get User uid inside StreamBuilder

I have an app which I want to display documents inside collection.. the collection reference is the uid of the user.

Is there a way to get current user uid and put this uid inside StreamBuilder in stream.

I have tried like so but it did not work and returned null:

class _MyAdsState extends State<MyAds> {

 final FirebaseAuth _auth = FirebaseAuth.instance;

Future getCurrentUser() async {
 final FirebaseUser user = await _auth.currentUser();
 final uid = user.uid;
 print(uid);
 return uid.toString();
}

@override
  Widget build(BuildContext context) {
   return Scaffold(
   
body: Column(
 Expanded(
          child: StreamBuilder<QuerySnapshot>(
            stream: Firestore.instance.collection("${getCurrentUser()}").snapshots(),
            builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> querySnapShot){
              if(querySnapShot.hasError){
                return Text('Some Error');
              }
              if(querySnapShot.connectionState == ConnectionState.waiting){
                return CircularProgressIndicator();
              }else{
                final list = querySnapShot.data.documents;

                return ListView.builder(
                    itemBuilder: (context, index){
                      return ListTile(
                        title: Text(list[index]["subject"]),
                        subtitle: Text(list[index]["category"]),
                      );
                    },
                  itemCount: list.length,
                );
              }
            },
          )

Upvotes: 2

Views: 2162

Answers (2)

humunuku01
humunuku01

Reputation: 11

THANK YOU GUYS!

I was looking for this for too long now. I had the "problem" that I was recording the senderUID for a sent message only, but of course wanted the Name being displayed in the "sentFrom" field. So I had to query Firestore for the UID and pull out the email. My solution:

FutureBuilder<QuerySnapshot>(
          future: _firestore.collection("users").get(),
          builder: (context, futureSnapshot) {
            if (!futureSnapshot.hasData) {
              return Center(
                child: CircularProgressIndicator(),
              );
            }

            Map<String, String> users = {};
            final userData = futureSnapshot.data.docs;
            for (var user in userData) {
              users[user.id] = user.data()["email"];
            }

            return StreamBuilder<QuerySnapshot>(
              stream: _firestore.collection("messages").snapshots(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                }
                // ignore: missing_return
                final messages = snapshot.data.docs;
                List<Widget> messageWidgets = [];
                for (var message in messages) {
                  final messageText = message.data()["text"];
                  final messageEmail = users[message.data()["senderUID"]];
                  messageWidgets
                      .add(Text("$messageText from $messageEmail"));
                }
                return Column(children: messageWidgets);
              },
            );
          },
        ),

I just created a map from the data and used it inside the stream builder. Is there maybe a better solution?

Upvotes: 0

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

Getting the UID is an asynchronous operation, so requires a FutureBuilder.

If you want to use the UID to then build a stream, you'll need to have a FutureBuilder for the UID, and then inside of that a StreamBuilder for the stream from the database.

body: FutureBuilder(
  future: FirebaseAuth.instance.currentUser(),
  builder: (context, AsyncSnapshot<FirebaseUser> snapshot) {
    if (snapshot.hasData) {
      return StreamBuilder<QuerySnapshot>(
        stream: Firestore.instance.collection(snapshot.data.uid).snapshots(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> querySnapShot){
          ...
        },
      )
    }
    else {
      return Text('Loading user data...');
    }

Upvotes: 2

Related Questions