【问题标题】:NoSuchMethodError: The method '[]' was called on null. Receiver: null Tried calling: []("favorites")NoSuchMethodError:在 null 上调用了方法“[]”。接收者:null 尝试调用:[]("favorites")
【发布时间】:2020-11-20 19:41:41
【问题描述】:

在每个用户身份验证和用户创建时,我都会收到一条错误消息,其中在 null 上调用该方法。

用户是在我注册时创建的,但它阻止我继续使用而无需重新启动应用程序。

我将所有与创建用户相关的调用都放在了firebase中,我找不到null的根本原因。


class AuthNotifier with ChangeNotifier {
  FirebaseUser _user;
  FirebaseUser get user => _user;

  void setUser(FirebaseUser user) {
    _user = user;
    _createUserDocument();
    if (user != null) {
      _createUserDocument();
    }
    notifyListeners();
  }

  void _createUserDocument() async {
    CollectionReference users = Firestore.instance.collection('Users');
    DocumentSnapshot user_document = await users.document(_user.uid).get();
    if (!user_document.exists) {
      // Create a document for the user if he doesn't have one
      users.document(_user.uid).setData({
        'favorites': []
      }
      );
    }
  }

  Future<void> toggleFavorite(String foodId) async {
    CollectionReference users = Firestore.instance.collection('Users');
    DocumentSnapshot user_document = await users.document(_user.uid).get();

    // If using collectionGroup, we can directly filter the foodId without looping through it.
    // Fetch and see if it is already in the list // TODO: Use class-wide, static, event-updated instance
    for (dynamic reference in user_document.data['favorites']) {
      if (reference.documentID == foodId) {
        // Remove it from the list and exit so it doesn't get added later in the function
        users.document(_user.uid).updateData({'favorites': FieldValue.arrayRemove([reference])}).catchError((error) => print("Failed to remove favorite element: ${error}"));
        notifyListeners();
        return;
      }
    }

    // Get the matching food DocumentReference object
    var food = await Firestore.instance.collection('Foods').document(foodId).get();
    // Add to the favorite list if it wasn't
    users.document(_user.uid).updateData({'favorites': FieldValue.arrayUnion([food.reference])}).catchError((error) => print("Failed to add new favorite element : ${error}"));
    notifyListeners();
  }

  Future<bool> isFavorite(String foodId) async {
    List<dynamic> favorites = await _getFavorites();
    for (DocumentReference favorite in favorites) {
      if (favorite.documentID == foodId) {
        return true;
      }
    }
    return false;
  }

  Future<List<dynamic>> getFavorites() async {
    List<dynamic> favorites = await _getFavorites();
    List<String> favorites_documentid = [];
    favorites.forEach((reference) { favorites_documentid.add(reference.documentID); });
    return favorites_documentid;
  }

  Future<List<dynamic>> _getFavorites() async {  // TODO: Use class-wide list that updates only when a a favorite is added or removed. Even listen to a snapshot for this, if there are lots of favorites.
    DocumentSnapshot snapshot = await Firestore.instance
        .collection('Users').document(_user.uid).get();
    return snapshot.data['favorites'];  // DocumentReference
  }

}

【问题讨论】:

  • 这意味着snapshot.data 为空
  • 谢谢,如何在尚未创建收藏列表的情况下将其集成到新用户中?

标签: flutter google-cloud-firestore favorites


【解决方案1】:

您需要await 才能完成异步操作。


  Future<void> setUser(FirebaseUser user) {
    _user = user;
    await _createUserDocument();
    if (user != null) {
      await _createUserDocument();
    }
    notifyListeners();
  }

  Future<void> _createUserDocument() async {
    CollectionReference users = Firestore.instance.collection('Users');
    DocumentSnapshot user_document = await users.document(_user.uid).get();
    if (!user_document.exists) {
      // Create a document for the user if he doesn't have one
      await users.document(_user.uid).setData({
        'favorites': []
      }
      );
    }
  }

await 也适用于 setUser()

更新。使用snapshot.data() 而不是snaphot.data

  Future<List<dynamic>> _getFavorites() async { 
    DocumentSnapshot snapshot = await Firestore.instance
        .collection('Users').document(_user.uid).get();
    return snapshot.data()['favorites'];  // DocumentReference
  }

【讨论】:

  • 错误消息仍然存在,收藏夹仍然为空...我应该返回或者如果收藏夹 != null ?
  • 该文档似乎存在,但由于之前的错误尝试不包含favorites 字段。转到 Firestore 控制台,删除带有 id 的文档,然后重试。
  • 没有收藏夹的登录正常,但收藏夹不存在的注册失败。我发现序列文档创建存在问题。
  • 使用 snapshot.data() 代替 snaphot.data:DocumentSnapshot 快照表达式不计算为函数,因此无法调用
猜你喜欢
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 2021-08-02
相关资源
最近更新 更多