Firebase 和 Flutter 是不是支持在 Web 上一次性读取?

Posted

技术标签:

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

我正在使用 Firebase 和 Flutter 来读取对象列表 (EspecieModel)。它在 iosandroid 上运行完美,但在 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 查询??

【问题讨论】:

【参考方案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 的原因,希望您可以使用它来帮助您找到确切的咒语。 --- 或者,您可以这样做:***.com/questions/61333194/…。在引入values 之前,我的大部分代码都使用了FrebaseList 嗨@puf。我想与您分享我评估每种替代方案的测试结果,请在我错的地方纠正我。我将它分为三个部分...

以上是关于Firebase 和 Flutter 是不是支持在 Web 上一次性读取?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter web 是不是有 AdMob 支持?

如何使用 Flutter/Dart 检查 Firebase 数据库中是不是存在节点

Flutter Firebase 是不是可以添加有关照片和照片的文本数据?

在 Flutter 中使用 Firebase 身份验证检查用户是不是是新用户

Flutter & Firebase:如何检查某个项目是不是存在于 Firebase 文档中的数组中

Flutter + Firebase:如何实现“谷歌登录”