【问题标题】:Updated to cloud_firestore 2.2.0 and cannot figure out the error更新到 cloud_firestore 2.2.0 并且无法找出错误
【发布时间】:2021-08-17 21:30:43
【问题描述】:

重构我的代码,我更新为

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^1.2.0
  firebase_auth: ^1.2.0
  cloud_firestore: ^2.2.0
  cloud_functions: ^1.1.0
  ...

例如cloud_firestore 从 1.0.4 到 2.2.0

我有一个用户类

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/widgets.dart';
import 'package:mypckg/services/database.dart';

class User {
  final String id;
  final String email;
  final String displayName;
  final String language;
  final List affiliatedOrganizations;
  final bool isAdmin;
  final bool isEditor;

  const User(
      {this.id = "",
      this.email = "",
      this.displayName = "",
      this.language = "",
      this.affiliatedOrganizations = const [],
      this.isAdmin = false,
      this.isEditor = false});

  factory User.fromFirestore(DocumentSnapshot doc) {
    Map data = doc.data()!;
    return User(
      id: doc.id,
      email: data['email'],
      displayName: data['displayName'] ?? '',
      language: data['language'] ?? '',
      affiliatedOrganizations: data['affiliatedOrganizations'] ?? [],
      isAdmin: data['isAdmin'] ?? false,
      isEditor: data['isEditor'] ?? false,
    );
  }
}

稍后我想获取一些数据

      ...
      var userData = await DatabaseService(uid: user.uid)
          .getUserData()
          .then((value) => value.data());

      local.User fullLocalUser = local.User(
          id: user.uid,
          email: user.email,
          displayName: userData!['displayName'] ?? "", // <-- error referencing this line
          language: userData['language'] ?? "",
          affiliatedOrganizations: userData['affiliatedOrganizations'] ?? [],
          isAdmin: (await _userClaims)!['admin'] == true,
          isEditor: (await _userClaims)!['editor'] == true);

      return fullLocalUser;
      ...

DatabaseService 的相关摘录

class DatabaseService {
  final String uid;
  DatabaseService({this.uid = ""});

  final CollectionReference usersCollection =
      FirebaseFirestore.instance.collection('users');
  
  ...
  Future<DocumentSnapshot> getUserData() async {
    print("get user data");
    return await usersCollection.doc(uid).get();
  }
  ...

当我编译代码时,结果是

Error: The operator '[]' isn't defined for the class 'Object'.
 - 'Object' is from 'dart:core'.
Try correcting the operator to an existing operator, or defining a '[]' operator.
          displayName: userData!['displayName'] ?? "",

我发现,关于https://pub.dev/packages/cloud_firestore/changelog“DocumentReference、CollectionReference、Query、DocumentSnapshot、CollectionSnapshot、QuerySnapshot、QueryDocumentSnapshot、Transaction.get、Transaction.set 和 WriteBatch.set 现在需要一个额外的通用参数。(#6015 )。”但我现在无法弄清楚我必须改变什么,代码将再次起作用:(

【问题讨论】:

  • 尝试使用Map userData = await DatabaseService... 而不是var userData = await DatabaseService...
  • Map userData ... 结果是The return type 'Map&lt;String, dynamic&gt;?' isn't a 'FutureOr&lt;Map&lt;dynamic, dynamic&gt;&gt;', as required by the closure's context.dart(return_of_invalid_type_from_closure),所以我设置了Map? userData = await ...,但这会导致Error: A value of type 'Object?' can't be returned from a function with return type 'FutureOr&lt;Map&lt;dynamic, dynamic&gt;?&gt;'. - 'Object' is from 'dart:core'. - 'Map' is from 'dart:core'. .then((value) =&gt; value.data());
  • 并使用Map&lt;dynamic, dynamic&gt; userData = await DatabaseService...
  • 已经尝试过这个,但结果是The return type 'Map&lt;String, dynamic&gt;?' isn't a 'FutureOr&lt;Map&lt;dynamic, dynamic&gt;&gt;', as required by the closure's context.dart(return_of_invalid_type_from_closure)
  • 不应该是return usersCollection.doc(uid).get();而不是getUserData()方法中的return await usersCollection.doc(uid).get();吗?

标签: google-cloud-firestore flutter-web


【解决方案1】:

我可以通过以下更改摆脱该错误。

用户类别:

...
class User {
  final String id;
  final String email;
  final String displayName;
  final String language;
  final List affiliatedOrganizations;
  final bool isAdmin;
  final bool isEditor;

  const User(
      {this.id = "",
      this.email = "",
      this.displayName = "",
      this.language = "",
      this.affiliatedOrganizations = const [],
      this.isAdmin = false,
      this.isEditor = false});

  User.fromJson(Map<String, Object?> json)
      : this(
          email: json['email']! as String,
          displayName: json['displayName'] as String,
          language: json['language'] as String,
          affiliatedOrganizations: json['affiliatedOrganizations'] as List,
          isAdmin: json['isAdmin'] as bool,
          isEditor: json['isEditor'] as bool,
        );

  Map<String, Object?> toJson() {
    return {
      'email': email,
      'displayName': displayName,
      'language': language,
      'affiliatedOrganizations': affiliatedOrganizations,
      'isAdmin': isAdmin,
      'isEditor': isEditor,
    };
  }

  factory User.fromFirestore(DocumentSnapshot doc) {
    print("---- factoring user ----");
    return User(
      id: doc.id,
      email: doc.get('email') ?? '',
      displayName: doc.get('displayName') ?? '',
      language: doc.get('language') ?? '',
      affiliatedOrganizations: doc.get('affiliatedOrganizations') ?? [],
      isAdmin: doc.get('isAdmin') ?? false,
      isEditor: doc.get('isEditor') ?? false,
    );
  }
}

数据库服务:

...
  final CollectionReference usersCollection = FirebaseFirestore.instance
      .collection('users')
      .withConverter<User>(
          fromFirestore: (snapshots, _) => User.fromJson(snapshots.data()!),
          toFirestore: (user, _) => user.toJson());
...
  Future<DocumentSnapshot> getUserData() async {
    print("get user data");
    return usersCollection.doc(uid).get();
  }
...

在这里我可以使用它:

...
      var userData = await DatabaseService(uid: user.uid).getUserData();

      local.User fullLocalUser = local.User(
          id: user.uid,
          email: user.email,
          displayName: userData['displayName'] ?? "",
          language: userData['language'] ?? "",
          affiliatedOrganizations: userData['affiliatedOrganizations'] ?? [],
          isAdmin: (await _userClaims)!['admin'] == true,
          isEditor: (await _userClaims)!['editor'] == true);

      return fullLocalUser;
...

感谢您的支持,逐步找到可行的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多