skip to Main Content

I’m trying to make a flutter app that allows users to log into an account and then store contact details in a firebase firestore. It currently shows the contact details for all registered accounts. I want the user to be able to see only their own contact details and not others, and I can’t figure out how to do this.

When added on the collection reference definition line, using .where() is returning:

A value of type ‘Query<Map<String, dynamic>>’ can’t be assigned to a variable of type ‘CollectionReference<Object?>’.

Database structure

class DatabaseService {

  final String ?uid;
  DatabaseService({ this.uid });

  //  collection reference
  final CollectionReference contactsCollection = FirebaseFirestore.instance.collection('contacts');

  Future updateUserData(String name, String phone) async {
    return await contactsCollection.doc(uid).set({
      'name': name,
      'phone': phone,
    });
  }

  // contacts list from snapshot

  List<Contacts> _contactsListFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.docs.map((doc){
      return Contacts(
        phone: doc.get('phone') ?? 0,
        name: doc.get('name') ?? ''
      );
    }).toList();
  }

  // userData from snapshot
  UserData _userDataFromSnapshot(DocumentSnapshot snapshot) {
    return UserData(
      uid: uid,
      name: snapshot['name'],
      phone: snapshot['phone'],
    );
  }

  //  get contacts stream
  Stream<List<Contacts>> get contacts {
    return contactsCollection.snapshots()
      .map(_contactsListFromSnapshot);
  }

  // get user doc stream
  Stream<UserData> get userData {
    return contactsCollection.doc(uid).snapshots()
        .map(_userDataFromSnapshot);
  }

}

2

Answers


  1. That error message seems correct, as calling where on a CollectionReference gives you back a Query. The simplest fix is to make the field implicitly type with just final:

    final contactsCollection = FirebaseFirestore.instance.collection('contacts').where(...);
    

    After that, I’m not sure what you want to filter on though, as the two fields showing in the screenshot (name and phone) don’t associate the document with a specific user as far as I can tell.

    Login or Signup to reply.
  2. You can use the .where as follows:

      Stream<List<Contacts>> get contacts {
        return contactsCollection
            .where('uid', isEqualTo: uid)
            .snapshots()
            .map(_contactsListFromSnapshot);
      }
    

    However, you should make sure that the fields have a uid:

    Future updateUserData(String name, String phone) async {
        return await contactsCollection.doc(uid).set({
          'uid': uid, // --> add this
          'name': name,
          'phone': phone,
        });
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search