Значение типа Object?
не может быть возвращено из метода getUser
, поскольку у него есть возвращаемый тип 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();
}
Почему будущее не завершится, хотя внутри явно есть UserModel
возвращение.
РЕДАКТИРОВАТЬ
Спасибо всем за ответы. Вот код или _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());}
Также вот код fromJson в моей 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);
РЕДАКТИРОВАТЬ Кажется, я решил проблему. Я не знаю, хорошее ли это решение, но я все равно был бы признателен за отзывы о том, что было не так, в первую очередь, ради обучения:)
Future<UserModel> getUser(String userId) async {
QuerySnapshot userDoc = await _usersCollectionRef.where('userId', isEqualTo: userId).get();
return userDoc.docs[0].data() as UserModel;}
QuerySnapshot — это универсальный класс QuerySnapshot<T extends Object?>
.
В объявлении userDoc
вы опустили параметр типа:
QuerySnapshot userDoc = await _usersCollectionRef.where(
'userId', isEqualTo: userId,
).get();
Вот почему T
по умолчанию имеет значение Object?
, а userDoc.docs[0].data()
предполагается, что он возвращает объект типа T
.
Анализатор не знает, что тип выполнения userDoc.docs[0].data()
будет UserModel
.
Пример с правильными параметрами типа:
import 'package:cloud_firestore/cloud_firestore.dart';
class UserModel {
UserModel({required this.name, required this.id});
final String name;
final int id;
factory UserModel.fromJson(Map<String, Object?> json) {
if (json case {'name': String name, 'id': int id}) {
return UserModel(name: name, id: id);
} else {
throw UnsupportedError('Could not convert $json to UserModel.');
}
}
Map<String, Object?> toJson() => {'name': name};
}
// usersRef is and instance of CollectionReference<UserModel>
final usersRef = FirebaseFirestore.instance
.collection('Sample_Path_User_Model')
.withConverter<UserModel>(
fromFirestore: (snapshots, _) => UserModel.fromJson(snapshots.data()!),
toFirestore: (movie, _) => movie.toJson(),
);
Future<UserModel> getUser(String userId) async {
QuerySnapshot<UserModel> userDoc =
await usersRef.where('userId', isEqualTo: userId).get();
return userDoc.docs[0].data();
}
Ваш объект userDoc
— это объект типа QuerySnapshot . Когда вы вызываете .docs[0]
, возвращается тип объекта QueryDocumentSnapshot . При дальнейшем вызове data() возвращается тип объекта T
, который является объектом универсального типа. Итак, это не экземпляр UserModel
, а карта, содержащая пары ключ-значение.
Если вы хотите преобразовать эти данные в объект класса UserModel
, вам необходимо создать метод функции fromMap()
, как описано в ответе из следующего сообщения: