Flutter:未处理的异常:错误状态:DocumentSnapshotPlatform中不存在字段

Posted

技术标签:

【中文标题】Flutter:未处理的异常:错误状态:DocumentSnapshotPlatform中不存在字段【英文标题】:Flutter: Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform 【发布时间】:2021-03-05 01:26:12 【问题描述】:

我是 Flutter 的新手,我正在通过教程构建一个社交媒体应用程序,我现在正在定制它。 现在我尝试向用户个人资料页面添加更多输入字段,然后我开始收到以下错误。当我可以登录时,我的时间线页面变成红色并带有警告Bad state: field does not exist within the DocumentSnapshotPlatform

我运行了Flutter clean,现在我的用户无法登录应用程序

我收到此错误:

E/flutter ( 3971): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform
E/flutter ( 3971): #0      DocumentSnapshotPlatform.get._findKeyValueInMap
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:82
E/flutter ( 3971): #1      DocumentSnapshotPlatform.get._findComponent
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:98
E/flutter ( 3971): #2      DocumentSnapshotPlatform.get
package:cloud_firestore_platform_interface/…/platform_interface/platform_interface_document_snapshot.dart:113
E/flutter ( 3971): #3      DocumentSnapshot.get
package:cloud_firestore/src/document_snapshot.dart:49
E/flutter ( 3971): #4      DocumentSnapshot.[]
package:cloud_firestore/src/document_snapshot.dart:56
E/flutter ( 3971): #5      new User.fromDocument
package:findemed/models/user.dart:46
E/flutter ( 3971): #6      _HomeState.createUserInFirestore
package:findemed/pages/home.dart:152
E/flutter ( 3971): <asynchronous suspension>
E/flutter ( 3971): #7      _HomeState.handleSignIn
package:findemed/pages/home.dart:60
E/flutter ( 3971): #8      _HomeState.initState.<anonymous closure>
package:findemed/pages/home.dart:46
E/flutter ( 3971): #9      _rootRunUnary (dart:async/zone.dart:1198:47)

首字母指向我家文件的这个 dart 部分

buildUsersToFollow() 
  return StreamBuilder(
    stream: usersRef.orderBy('timestamp', descending: true)
    .limit(0)
    .snapshots(),
    builder: (context, snapshot) 
      if (!snapshot.hasData) 
        return circularProgress(context);
      
      List<UserResult> userResults = [];
      snapshot.data.docs.forEach((doc) 
        User user = User.fromDocument(doc);
        final bool isAuthUser = currentUser.id == user.id;
        final bool isFollowingUser = followingList.contains(user.id);
        // remove auth user from recommended list
        if (isAuthUser) 
          return;
         else if (isFollowingUser) 
          return;
         else 
          UserResult userResult = UserResult(user);
          userResults.add(userResult);
        
        );


现在它指向这个sn-p:

factory User.fromDocument(DocumentSnapshot doc) 
    return User(
      id: doc['id'],
      email: doc['email'],
      username: doc['username'],
      photoUrl: doc['photoUrl'],
      displayName: doc['displayName'],
      bio: doc['bio'],      
      fullNames: doc['fullNames'],
      practice: doc['practice'],
      speciality: doc['speciality'],
      phone: doc['phone'],
      mobile: doc['mobile'],
      emergency: doc['emergency'],
      address: doc['address'],
      city: doc['city'],
      location: doc['location'],
    );
  

这是堆栈中指出的另一段代码

currentUser = User.fromDocument(doc);
    print(currentUser);
    print(currentUser.username);

【问题讨论】:

请将问题编辑为 1) 指出此错误所指的代码行,以及 2) 明确说明您希望此代码执行的操作(尤其是考虑到您要求限制为 0 个文档) . 【参考方案1】:

此错误是因为,您从文档中调用的字段不存在。即使是单个字段也可能导致此错误。

【讨论】:

【参考方案2】:

假设final Map&lt;String, dynamic&gt; doc 这样您就可以检查doc 变量doc.keys.contains('anyField') 中的任何可用字段,如果字段可用则为真,否则为假。

【讨论】:

【参考方案3】:

使用这个:

Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
data['SOMEKEY'].toString();
int.parse(data['SOMEKEY'].toString());
for boolean use if(data['SOMEKEY'] == true)

【讨论】:

【参考方案4】:

**

确保构建器上的文档名称与 您的 Firestore 数据库文档名称。

**

【讨论】:

【参考方案5】:

错误(错误状态:文档中不存在字段)仅在您在 Flutter 代码中键入区分大小写的字段名称或在您的 firestore 集合字段中存在的字段名称时发生。

记住字段名称区分大小写,因此您必须使用与您的 Firestore 集合字段中提到的相同的字段

例如:-您的 Firebase Firestore 集合字段包含“用户名”字段,并且您在 Flutter 代码中使用了“用户名”,然后会发生此错误。因此,要修复此错误,请使用与 Firestore 中提到的相同的字段名称

这是 Cloud FireStore 集合字段包含 “用户名”等,因此您必须在 Flutter 代码中使用完全相同 Check Cloud FireStore Collection Fields

由于大小写敏感这是正确的,因为集合字段在 Firestore 集合中以 ("UserName") 的形式存在,并在 Flutter 代码中使用 ("UserName")

Correct FieldName forFlutter Code 由于大小写敏感性这是错误的,因为集合字段在 Firestore 集合中以 ("UserName") 的形式存在,并在 Flutter 代码中使用 ("username") Wrong FieldName forFlutter Code

如果您需要更多帮助,请联系我... 快乐编码

【讨论】:

【参考方案6】:

除非您不小心,否则此错误与代码无关。数据库中的字段与其类中的数据可能存在差异。

示例: 班级学生字符串?名称,字符串?部门,字符串?学校

数据库: 1-> 名称=xxx,没有=xxx 2->名称=yyy,no=yyy,学校=yyy

所有字段必须正确匹配。

【讨论】:

【参考方案7】:

检查所有数据的 Firebase 和 Local 值是否相同,即 doc['id']

这里的 'id' 是与您的 Firestore 中相同的密钥检查。

id: doc['id'],
  email: doc['email'],
  username: doc['username'],
  photoUrl: doc['photoUrl'],
  displayName: doc['displayName'],
  bio: doc['bio'],      
  fullNames: doc['fullNames'],
  practice: doc['practice'],
  speciality: doc['speciality'],
  phone: doc['phone'],
  mobile: doc['mobile'],
  emergency: doc['emergency'],
  address: doc['address'],
  city: doc['city'],
  location: doc['location'],

检查并重新运行

【讨论】:

【参考方案8】:

对于最新版本的cloud_firestore: ^2.4.0,我终于找到了解决方案:

而旧版本的 cloud_firestore 解决方法是在末尾简单地添加 ?? 以避免出现空值:

factory User.fromDocument(DocumentSnapshot doc) 
   return User(
      id: doc.data()['id'] ?? '',
   );

但在新版本中这是不可能的,因为返回 Bad state

factory User.fromDocument(DocumentSnapshot doc) 
   return User(
       id: doc.get('id')
   );

只需检查文档是否包含密钥即可解决:

factory User.fromDocument(DocumentSnapshot doc) 
   return User(
      id: doc.data().toString().contains('id') ? doc.get('id') : '',
   );

希望这会有所帮助,问候! :)

【讨论】:

【参考方案9】:

把你的工厂改成这样:

factory User.fromDocument(DocumentSnapshot doc) 
  return User(
    id: doc.data()['id'],
    email: doc.data()['email'],
    username: doc.data()['username'],
    photoUrl: doc.data()['photoUrl'],
    displayName: doc.data()['displayName'],
    bio: doc.data()['bio'],      
    fullNames: doc.data()['fullNames'],
    practice: doc.data()['practice'],
    speciality: doc.data()['speciality'],
    phone: doc.data()['phone'],
    mobile: doc.data()['mobile'],
    emergency: doc.data()['emergency'],
    address: doc.data()['address'],
    city: doc.data()['city'],
    location: doc.data()['location'],
  );

【讨论】:

更改为doc.data() 解决了一个问题,然后我必须通过将.limit(0) 设为正整数来解决它并运行 我试过这个,但它给出了运算符'[]'没有为类型'Object'定义。 @s3v3ns 您可以使用此解决方法来解决该错误。 (e.data() as dynamic)['field']。丑陋但有效。或者创建一个动态别名final _snapshot = snapshot as dynamic;。也许有更好的方法,我还在学习。 感谢阿德里安,非常有用的解决方法。有没有解释为什么要转换为动态作品?当我收到@s3v3ns 提到的错误时,我正在使用context.watch&lt;DocumentSnapshot&gt;().data()【参考方案10】:

简单的解决方案是使用 DocumentSnapshot 中的 data() 并将其转换为 Map,最后您可以检查 key 是否存在于地图上,如给定代码 sn-ps 中所示。

fireStore.collection('transactions').get().then((QuerySnapshot querySnapshot) 
  List<TransactionModel> transactions = [];
  querySnapshot.docs.forEach((DocumentSnapshot doc) 
    transactions.add(TransactionModel.fromJson(doc.data() as Map<String,dynamic>));
  );
  onResponse(FireStoreApiResponse.withSuccess(transactions));
).catchError((onError) 
  onResponse(FireStoreApiResponse.withError(onError));
);

在 TransactionModel 类中

TransactionModel.fromJson(Map<String, dynamic> json) 
date = json['date'];
memberId = json['member_id'];
if (json.containsKey("member_contact")) memberContact = json['member_contact'];
if (json.containsKey("member_name")) memberName = json['member_name'];
packageId = json['package_id'];
grossAmount = json['gross_amount'];
discount = json['discount'];
netAmount = json['net_amount']; 

【讨论】:

【参考方案11】:

而不是使用这个:

factory User.fromDocument(DocumentSnapshot doc) 
    return User(
      id: doc['id'],
      email: doc['email'],
      username: doc['username'],
      photoUrl: doc['photoUrl'],
      displayName: doc['displayName'],
      bio: doc['bio'],      
      fullNames: doc['fullNames'],
      practice: doc['practice'],
      speciality: doc['speciality'],
      phone: doc['phone'],
      mobile: doc['mobile'],
      emergency: doc['emergency'],
      address: doc['address'],
      city: doc['city'],
      location: doc['location'],
    );
  

我用过 ::

factory User.fromDocument(DocumentSnapshot doc) 
    return User(
      id: doc.get('id'),
      email: doc.get('email'),
      username: doc.get('username'),
      photoUrl: doc.get('photoUrl')
      displayName: doc.get('displayName'),
      bio: doc.get('bio'),      
      fullNames: doc.get('fullNames'),
      practice: doc.get('practice'),
      speciality: doc.get('speciality'),
      phone: doc.get('phone'),
      mobile: doc.get('mobile'),
      emergency: doc.get('emergency'),
      address: doc.get('address'),
      city: doc.get('city'),
      location: doc.get('location'),
    );
  

它为我解决了问题...

【讨论】:

【参考方案12】:

我也有同样的问题。后来发现是由于Firestore中键名的尾随空格造成的。

【讨论】:

【参考方案13】:

我通过更改查询以更新数据库中的值而不是设置它们来解决此错误,因为显然一个字段正在被删除,因此无法检索其值。 这可以帮助面临同样错误并与我的设置相同的人。

【讨论】:

【参考方案14】:

我遇到了同样的问题,我通过询问参数是否存在来解决它。

这是我之前的代码:

if(widget.document['imageUrl'] == null)//here was my error, I was calling a field that did not exist in the document
  Container(
    child:Icon(
      Icons.image,
      size: 20.0,
      color: Colors.grey,
    ),
  ),

这对我来说是这样的:

if(widget.document.data().containsKey('imageUrl'))
  Container(
    child:Icon(
      Icons.image,
      size: 20.0,
      color: Colors.grey,
    ),
  ),

【讨论】:

【参考方案15】:

当您调用的文档为空时也会发生这种情况。

【讨论】:

【参考方案16】:

更好更简单的方法

factory User.fromDocument(DocumentSnapshot snap) 

   var doc = snap.data();
   id: doc['id'],
   email: doc['email'],
   ......
   ......
      

【讨论】:

【参考方案17】:

在生成器方法中显示文档数据时,传递文档中不存在的错误属性名称也可能发生此问题。 这为我解决了这个问题。

【讨论】:

谢谢兄弟。使用 firebase,我只需将 doc['id'] 替换为 doc.get('id')【参考方案18】:

我认为这是因为 .limit(0) 子句。

【讨论】:

以上是关于Flutter:未处理的异常:错误状态:DocumentSnapshotPlatform中不存在字段的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:未处理的异常:错误状态:调用关闭后无法添加新事件(不一样的情况)

未处理的异常:错误状态:平台不允许使用不安全的 HTTP - usesClearTextTraffic 不起作用

Flutter 中的错误:未处理的异常:“Null”类型不是“String”类型的子类型

错误:flutter/lib/ui/ui_dart_state.cc(148) 未处理的异常

Flutter未处理的异常:SocketException:操作系统错误:连接被拒绝,errno = 111

Flutter [错误:flutter/lib/ui/ui_dart_state.cc(177)] 未处理的异常:类型“int”不是类型转换中“String”类型的子类型