Я не могу заставить Future завершиться со значением

Значение типа 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;}

Пожалуйста, добавьте объявление _usersCollectionRef в свой код. Возможно, отсутствует параметр типа.

Ber 15.08.2024 17:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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();
}

Итак, как ОП применяет это для исправления своего кода? Не могли бы вы добавить исправленный код?

Ber 15.08.2024 17:06

Я бы предложил явно объявить userDoc как QuerySnapshot<UserModel> и проверить, что при создании CollectionReference использовался тот же параметр типа.

Dan R 15.08.2024 20:26

Когда я это делаю, я получаю сообщение об ошибке: значение типа «QuerySnapshot<Object?>» не может быть присвоено переменной типа «QuerySnapshot<UserModel>».

ogz stn 16.08.2024 07:11
Ответ принят как подходящий

Ваш объект userDoc — это объект типа QuerySnapshot . Когда вы вызываете .docs[0], возвращается тип объекта QueryDocumentSnapshot . При дальнейшем вызове data() возвращается тип объекта T, который является объектом универсального типа. Итак, это не экземпляр UserModel, а карта, содержащая пары ключ-значение.

Если вы хотите преобразовать эти данные в объект класса UserModel, вам необходимо создать метод функции fromMap(), как описано в ответе из следующего сообщения:

Спасибо за отличное объяснение, все логично. Но у меня уже есть функция fromJson() (я поставил ее в конце вопроса). Когда я попытался добавить функцию fromMap(), возникла та же проблема.

ogz stn 16.08.2024 07:22

Что произойдет, если вы преобразуете userDoc.docs[0].data() в объект типа UserModel?

Alex Mamo 16.08.2024 07:30

Я думаю, что последний бит, который я отредактировал, делает это, и это решает проблему, но я все еще не понимаю, что было не так в первую очередь.

ogz stn 16.08.2024 07:35

Я собирался написать вам просто для того, чтобы превратить userDoc.docs[0].data() в UserModel. Я рад, что вы отредактировали свой вопрос. Я также отредактировал свой ответ.

Alex Mamo 16.08.2024 07:47

Помог ли мой ответ/комментарий? Могу ли я помочь вам с другой информацией?

Alex Mamo 16.08.2024 07:47

Да, большое спасибо. Я бы проголосовал за это, но у меня нет репутации :)

ogz stn 16.08.2024 08:18

Другие вопросы по теме