没有为类型“Object”定义运算符“[]”。尝试定义运算符“[]”。尝试从 Firestore 获取数据时出错

时间:2021-05-29 09:57:53

标签: firebase flutter dart

我正在尝试从 Firestore 中存储的文档中检索数据。我已经尝试了好几次来找到解决此错误的方法,但一直没有找到有用的东西。

这是我的代码。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class GetUserName extends StatelessWidget {
  final String documentId;

  GetUserName(this.documentId);

  @override
  Widget build(BuildContext context) {
    CollectionReference users = FirebaseFirestore.instance.collection('Drivers');

    return FutureBuilder<DocumentSnapshot>(
      future: users.doc(documentId).get(),
      builder:
          (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {

        if (snapshot.hasError) {
          return Text("Something went wrong");
        }

        if (snapshot.hasData && !snapshot.data!.exists) {
          return Text("Document does not exist");
        }

        if (snapshot.connectionState == ConnectionState.done) {
          Object? data = snapshot.data!.data();
          return Text(data!['username']);
        }

        return Text("loading");
      },
    );
  }
}

当我尝试从数据中检索“用户名”时发生错误。

感谢您的帮助

1 个答案:

答案 0 :(得分:3)

问题在于Objectdynamic的区别。

在 Dart 中,Object? 是“顶级类型”,这实质上意味着:“所有值都是 Object?”。

dynamic 通常用于类似的情况(当您不知道正在处理的数据类型,并且不希望类型系统向您抱怨时),但它具有很不一样的意思。简而言之,它的意思是“关闭类型检查,因为我知道我在做什么”。

Object?dynamic 之间的主要区别在于它们的成员。

Object? 上定义了几个成员:

  • toString()
  • runtimeType
  • hashCode
  • noSuchMethod(Invocation invocation)

所有对象共享这些成员,因为所有对象都是 Object?。 如果你有一个静态类型 Object? 的值,这些是 Dart 可以保证存在的唯一 4 个成员,所以这些是你唯一被允许调用的(就像你尝试调用时会得到错误一样)致电"some string".notARealMethod())。

dynamic 做相反的事情:它假设所有可能的成员都存在,并且从不向您发出任何访问警告,例如:

String s = "hello";
s.notARealMethod();  // compile time error
final d = s as dynamic;  // explicitly cast to dynamic
d.notARealMethod();  // now throws at runtime

所以,回到你的代码,你有这个:

Object? data = snapshot.data!.data();
return Text(data!['username']);

data 是一个 Object?,所以 data! 是一个 Object,正如我们之前看到的,Object 上仅有的 4 个成员是:{{ 1}}、toString()runtimeTypehashCode。所以 Dart 会抱怨,因为它不能保证 noSuchMethod(Invocation invocation) 存在。

要解决此问题:

  1. 使用 [] 而不是 dynamic。它不会给你一个编译错误,但如果值最终没有 Object? 运算符,它会在运行时抛出(尽管因为这是来自 firestore,这是一个安全的赌注)

  2. 使用类型检查(并使用类型提升):

[]