flutterfirebasedartgoogle-cloud-platformgoogle-cloud-firestore

I can't get Future to complete with a value


A value of type Object? can't be returned from the method getUser because it has a return type of Future\<UserModel\>.

  Future<UserModel> getUser(String userId) async {
    QuerySnapshot userDoc = await _usersCollectionRef.where('userId', isEqualTo: userId).get();
    print('user doc: ${userDoc.docs[0].data()}'); //user doc: Instance of 'UserModel'
    return userDoc.docs[0].data();
  }

Why won't the future complete even though there clearly is a UserModel inside the return.

EDİT Thank you all for the replies. Here is the code or _usersCollectionRef

  FirestoreDatabase() {
_folderCollectionRef = _firestore.collection(FOLDERS_COLLECTON_REF).withConverter<FolderModel>(
    fromFirestore: (snapshots, _) => FolderModel.fromJson(
      snapshots.data()!,
    ),
    toFirestore: (folderModel, _) => folderModel.toJson());

_usersCollectionRef = _firestore.collection(USERS_COLLECTION_REF).withConverter<UserModel>(
    fromFirestore: (snapshots, _) => UserModel.fromJson(
      snapshots.data()!,
    ),
    toFirestore: (userModel, _) => userModel.toJson());}

Also here is the code for fromJsonin my UserModel:

UserModel.fromJson(Map<String, Object?> json)
  : this(
nickName: json['nickName']! as String,
userId: json['userId']! as String,
email: json['email']! as String,
role: json['role']! as String);

EDİT I seem to have solved the problem. I don't know if this is a good solution, but I would still appreciate feedback as to what was wrong in the first place for the sake of learning:)

  Future<UserModel> getUser(String userId) async {
QuerySnapshot userDoc = await _usersCollectionRef.where('userId', isEqualTo: userId).get();
return userDoc.docs[0].data() as UserModel;}

Solution

  • Your userDoc object is an object of type QuerySnapshot. When you call .docs[0] the type of object that is returned is QueryDocumentSnapshot. When you further call data(), the type of object that is returned is T, which is a generic type object. So it's not an instance of UserModel but a Map that contains key-value pairs.

    If you want to convert that data into an object of the UserModel class, then you have to create a fromMap() function method as explained in the answer from the following post: