【问题标题】:Do Firebase and Flutter support one-time reads on the web?Firebase 和 Flutter 是否支持在 Web 上一次性读取?
【发布时间】:2022-01-03 08:23:09
【问题描述】:

我正在使用 Firebase 和 Flutter 来读取对象列表 (EspecieModel)。它在 IOS 和 Android 上运行完美,但在 Web 上无法运行(检索到空列表)。

我正在阅读 Firebase 如下...

Future<List<EspecieModel>> cargarTipoEspecie() async {

  final List<EspecieModel> tipoEspecie = []; 

  Query resp = db.child('PATH/tipoespecie');
  resp.onChildAdded.forEach((element) {
        final temp = EspecieModel.fromJson(Map<String,dynamic>.from(element.snapshot.value));
        temp.idEspecie = element.snapshot.key;
        tipoEspecie.add(temp);   
  });
  await resp.once().then((snapshot) {
    print("Loaded - ${tipoEspecie.length}");
  });
      return tipoEspecie;

}

我正在使用 Future Builder 来显示信息...

FutureBuilder(
        future: _tipoEspecieBloc.cargarTipoEspecie(), 
        builder: (BuildContext context, AsyncSnapshot snapshot) {
            // print(snapshot.connectionState);
            if (snapshot.connectionState == ConnectionState.done && snapshot.hasData{
              // print(snapshot.data);
              final _especies = snapshot.data;
                   return Stack(
                    children: <Widget>[
                      ListView.builder(
                        itemCount: _especies!.length,
                        itemBuilder: (context, i) { 
                          return _crearItem(context, _especies[i], i);
                        },
                      ),
                    ],
                  );   
            } else if (snapshot.hasError) {
              print(snapshot.error);
              return Text(snapshot.error.toString());
            }
            else {
              return //CircleProgressIndicator Code
            );
            }
        },
      ),

我无法确定自己做错了什么

如何做一个在 IOS、Android 和 Web 上都运行良好的一次性 Firebase 查询??

【问题讨论】:

    标签: flutter firebase-realtime-database flutter-web


    【解决方案1】:

    这行不通:

    resp.onChildAdded.forEach((element) {
         final temp = EspecieModel.fromJson(Map<String,dynamic>.from(element.snapshot.value));
         temp.idEspecie = element.snapshot.key;
         tipoEspecie.add(temp);   
    });
    await resp.once().then((snapshot) {
     print("Loaded - ${tipoEspecie.length}");
    });
    return tipoEspecie;
    

    onChildAdded 不是await 的一部分,所以我怀疑一切都按照你想要的方式等待。只需在一处添加await,不会使其余代码同步。

    请考虑只使用once(),然后通过循环snapshot.value.values(一个相对较新的addition to the API)来填充您的tipoEspecie数组。

    var snapshot = await resp.once();
    snapshot.value.values.forEach((node) {
      final temp = EspecieModel.fromJson(Map<String,dynamic>.from(node.value));
      temp.idEspecie = node.key;
      tipoEspecie.add(temp);   
    });
    return tipoEspecie;
    

    注意:我不完全确定 .forEach 和其中的代码。因此,如果您在那里遇到错误,请检查您从 .values 返回的类型以及 node 是什么,以从中获取正确的键和值。

    【讨论】:

    • 谢谢@puf。它给出了一个错误:NoSuchMethodError: 'values' method not found Receiver: null Arguments: [].
    • 一年前,我实现了一个这种类型的查询...var snapshot = await resp.once(); snapshot.value.forEach((id, item){ final temp = EspecieModel.fromJson(Map&lt;String,dynamic&gt;.from(item)); temp. idEspecie = id; tipoEspecie.add(temp); });我刚刚看到它在网络上运行良好,但是在IOS和Android上使用时遇到了很多问题在在线/离线场景中。这就是我切换到 OnChild 方法的原因
    • 您是否知道任何与 onChildAdded 类似的查询在 Web 上有效(我确信它在 IOS 和 Android 上有效 - 开/关场景)?
    • 如果您有最新的 SDK,values 将在所有受支持的平台上的 once() 侦听器中为您提供排序结果。如前所述,我并不完全确定语法,这就是我链接 PR 的原因,希望您可以使用它来帮助您找到确切的咒语。 --- 或者,您可以这样做:stackoverflow.com/questions/61333194/…。在引入values 之前,我的大部分代码都使用了FrebaseList
    • 嗨@puf。我想与您分享我评估每种替代方案的测试结果,请在我错的地方纠正我。我将它分为三个部分...
    猜你喜欢
    • 2020-12-24
    • 2020-08-06
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多