颤动时无法从firestore获取文件

时间:2021-04-25 01:27:35

标签: firebase flutter google-cloud-firestore

我正在尝试从 Firestore 数据库中获取 brews 集合中的文档。

我编写了如下代码,但它的数组为空。

我的代码有什么问题?

帮助我一个习惯了颤抖和火力的人。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:brew_crew/models/brew.dart';

class DatabaseService {

  final String uid;
  DatabaseService({ this.uid });

  // collection references
  final CollectionReference brewCollection = FirebaseFirestore.instance.collection("brews");

~~~ short cut ~~~

  // brew list from snapshot
  List<Brew> _brewListFromSnapshot(QuerySnapshot snapshot) {
    print(snapshot.docs.length); // return 0.
    // print(snapshot.docs.toString()); // here this returns [].
    return snapshot.docs.map((doc) {
      return Brew(
        name: doc.data()['name'] ?? '',
        strength: doc.data()['strength'] ?? 0,
        sugars: doc.data()['sugars'] ?? 0,
      );
    }).toList();
  }

  Stream<List<Brew>> get brews {
    return brewCollection.snapshots()
        .map(_brewListFromSnapshot);
  }
}

使用流添加代码

home.dart

import 'package:brew_crew/screens/services/auth.dart';
import 'package:brew_crew/screens/services/database.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:brew_crew/screens/home/brew_list.dart';

class Home extends StatelessWidget {

  final AuthService _auth = AuthService();

  @override
  Widget build(BuildContext context) {
    return StreamProvider<List<Brew>>.value(
      value: DatabaseService().brews, // here using the stream.
child: Scaffold(

~~~ short cut ~~~

        body: BrewList(), // here too.
      ),
    );
  }
}

这是一个用于主屏幕页面的文件,使 DatabaseService 实例调用 brews 流。

这是将 brews 流作为值传递给 Provider,该值在 body 中的 BrewList 实例中调用。

brew_list.dart

import 'package:brew_crew/models/brew.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class BrewList extends StatefulWidget {
  @override
  _BrewListState createState() => _BrewListState();
}

class _BrewListState extends State<BrewList> {
  @override
  Widget build(BuildContext context) {
    final brews = Provider.of<List<Brew>>(context);
    brews.forEach((brew) {
      print(brew.name);
      print(brew.sugars);
    });
    // print(brews.toString()); // here returns [] too.
    return Container();
  }
}

在 BrewList 类中,只调用 Provider 值。

已添加

brew_list.dart

print(brews.length);

返回

Performing hot reload...
Syncing files to device iPhone 8...
flutter: 0
Reloaded 4 of 667 libraries in 253ms.
flutter: 0
flutter: 0

已添加

在 brew_list.dart 中使用 forEach 时出现此错误。

The following NoSuchMethodError was thrown building BrewList(dirty, dependencies: [_InheritedProviderScope<List<Brew>>], state: _BrewListState#eaba8):
The method 'forEach' was called on null.
Receiver: null
Tried calling: forEach(Closure: (Brew) => Null)

3 个答案:

答案 0 :(得分:0)

您的 Print 正在尝试将对象数组转换为无效或 Stringable 的字符串,因为它也包含循环引用。 但是,snapshot.docs 是可迭代的,使用 forEach 将根据您的需要处理每个文档。

只需确保在处理快照之前完成快照,方法是根据需要在您的 Stream Provider 中等待或处理它。

您可以使用 snapshot.docs.length 检查文档的数量,如果您看到返回值,则必须进一步调试。

答案 1 :(得分:0)

您收到该错误是因为您正在尝试输出尚未完全提取的数据。您的流正在从 Firestore 获取数据,但需要时间将其全部发送出去。因此,我建议使用像 ?? 这样的空感知运算符,或者只是检查自己是否为空,如果不是,则同时显示不同的小部件。

final brews = Provider.of<List<Brew>>(context);

    return brews == null ? CircularProgressIndicator() :
          ListView.builder(
            itemCount: brews.length,
            itemBuilder: (context, index) {
              return Text("${brews[index].name}");
            },
          );

答案 2 :(得分:0)

抱歉,我注意到我弄错了集合名称。 不是“酿造”而是“酿造”。

非常感谢您帮助我。