从Firebase获取数据并在Flutter、Dart中创建对象

Obtaining data from Firebase and creating an object in Flutter, Dart

我想使用我的 Firebase 数据库中的数据创建一个对象。我正确地获取了数据,但我无法按照我尝试的方式创建该 Objet。我不知道为什么它不起作用,这是我第一次使用 Dart。

这是我的代码

MaterialQR selectFromFirebase(String document) {
    MaterialQR res = MaterialQR(exercises: [], image: '', name: '', id: '');
    FirebaseFirestore.instance.collection('MaterialQR')
        .doc(document).get()
        .then((value) => res = new MaterialQR(
          exercises: value['exercises'],
          image: value['image'],
          name: value['name'],
          id: value['id']));
    return res;
  }

如果我的数据库中的文档不存在,objective 是 return 一个“空”对象,如果文档存在,return 是一个正确的对象。当我在 .then()print(value['id']) 时,我得到了正确的 id,但是当我创建新对象时它不起作用。

这是因为数据是从 Firestore(以及几乎任何现代云 API)异步加载的,因为它可能需要一些时间才能可用。在此期间,您的主要代码实际上并没有阻塞您的代码(和用户),而是继续执行。然后,当数据可用时,您的 then 块就会执行。

如果您在代码中放置一些日志记录,运行 并检查其输出,这是最容易看到的。

print('Before starting to read from the database');
FirebaseFirestore.instance.collection('MaterialQR')
    .doc(document).get()
    .then((value) => {
      print('got data from the database');
    });
print('After starting to read from the database');

这个输出是:

Before starting to read from the database

After starting to read from the database

Got data from the database

这可能不是您所期望的,但它完美地解释了为什么您没有从 selectFromFirebase 中得到结果:res 之前的 return res 运行由您的 then 块设置。


无法阻止调用的这种异步性质。相反,您必须接受调用云 APIs 是异步的,并且方法中的 return a Future 和标记为 async:

Future<MaterialQR> selectFromFirebase(String document) async {

这也意味着您可以在其中使用 await,因此整个函数变为:

Future<MaterialQR> selectFromFirebase(String document) async {
  try {
    var value = await FirebaseFirestore.instance.collection('MaterialQR')
      .doc(document).get();
    return MaterialQR(
      exercises: value['exercises'],
      image: value['image'],
      name: value['name'],
      id: value['id']);
  }
  catch {
    return  MaterialQR(exercises: [], image: '', name: '', id: '');
  }
}

另请参阅: