skip to Main Content

Am trying to get data for a specific user only using flutter and firestore latest version.
Since firebase has been updated the latest version does’t work with the methods I’ve seen online.

Here’s my stream builder

final currentUser = FirebaseAuth.instance.currentUser;
//Streams are used to listen to realtime streams of data

@override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: _usersStream,
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }
        return ListView(
          children: snapshot.data!.docs.map((DocumentSnapshot document) {
            Map<String, dynamic> data =
                document.data()! as Map<String, dynamic>;
            return Row(
              children: [
                Text(data['first name']),
                Text(data['last name']),
              ],
            );
          }).toList(),
        );
      },
    );
  }

I want to do queries with the ‘uid’, This gets all the current users data.

I tried this as the stream query but doesn’t work

final Stream<QuerySnapshot> _myUserStream = FirebaseFirestore.instance.collection('users').doc(currentUser!.uid).snapshots(); your text

I also tried this

final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('users').where('email', currentUser.email).snapshots();

2

Answers


  1. Chosen as BEST ANSWER

    For those wonder what I did.

    First I get the user id of the current user.

    FirebaseAuth.instance.currentUser!.uid
    

    The when am creating a profile I pass that id to the user data.

    UserProfile userProfile = UserProfile(
        firstName: 'First Name',
        lastName: 'Last Name',
        uid: FirebaseAuth.instance.currentUser!.uid);
    
    databaseService.addUser(userProfile);
    

    The databaseService is a custom class with the database functions. Here's the databaseService class addUser(userProfile) function. UserProfile is the model that takes the variables.

    addUser(UserProfile userProfile) async {
        await _db
            .collection("users")
            .doc(FirebaseAuth.instance.currentUser!.uid)
            .set(userProfile.toMap());
    }
    

    Here's the user profile class also.

    class UserProfile {
        final String? id;
        final String firstName;
        final String lastName;
        final String uid;
    
        UserProfile({
            this.id,
            required this.firstName,
            required this.lastName,
            required this.uid,
        });
    

    So when am query the data base for a specific user.

    final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance
        .collection('users')
        .where('uid', isEqualTo: FirebaseAuth.instance.currentUser!.uid)
        .snapshots();
    

    The data I get from the stream has to be used in a streambuilder to access that data. so _usersStream is like the query and the streambuilder displays data from that query.

    // StreamBuilder takes a stream
    StreamBuilder<QuerySnapshot>(
        stream: _usersStream // This is the query for the stream builder
    

    Now to extract that data, check if the data is received successfully. The data received is passed to a Map. I can then convert that Map to an Object. Object would be like a class which in my case is UserProfile.

    if (snapshot.connectionState == ConnectionState.done) {
        Map<String, dynamic> data =
            snapshot.data!.data() as Map<String, dynamic>;
    
        // Pass data from map to class
        userData = UserProfile(
            firstName: data['first name'],
            lastName: data['last name'],
            uid: data['uid']);
    
        // Display data from user data
        return Text("Full Name: ${userData.firstName}");
    }
    

    I can then use the userData to do what I want, display information etc. Pass to other screens all of that.


  2. Lets say Users is a model you made.
    in my case its this.

      Users.fromMap(Map<String, dynamic> map) {
    uid = map['uid'];
    userName = map['userName'];
    userNickname = map['userNickname'];
    userBirthday = map['userBirthday'];
    userEmail = map['userEmail'];
    userPassword = map['userPassword'];
    userGender = map['userGender'];
    userImage = map['userImage'];
    userData = (map['userData'] as Map<String, dynamic>?)?.map((key, value) =>
        MapEntry(key, value is List ? List<String>.from(value) : <String>[]));
    

    }

    You can get the User data using Future this way

      Users user = await FirebaseFirestore.instance
          .collection('users')
          .snapshots()
          .map((event) {
        return event.docs.map((e) {
        
          return Users.fromMap(e.data());
        }).singleWhere(
          (element) => element.userEmail == email,
        );
      }).first;
    

    enter image description here
    For Streams this way

       var snapshot = await FirebaseFirestore.instance
          .collection('users')
          .snapshots()
          .first;
      Users user = snapshot.docs
          .map((e) => Users.fromMap(e.data()))
          .singleWhere((element) => element.userEmail == email);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search