【问题标题】:Read list of items from firebase database flutter从 firebase 数据库中读取项目列表
【发布时间】:2020-11-01 12:26:03
【问题描述】:

我正在尝试从此数据库中构建项目列表:

但我收到此错误:

_TypeError (type 'List<dynamic>' is not a subtype of type 'List<DataSnapshot>')

我可以使用 snap2.value 获取项目值,但我需要获取元素键,因为它是我的项目 ID,以构建我的列表。

import 'package:firebase_database/firebase_database.dart';
final DatabaseReference _refdata =
    FirebaseDatabase.instance.reference().child('host');

getItems() async {
  String _refOnline;
  await _refdata.child("ref").once().then((value) => _refOnline = value.value);
  if (dataRef != _refOnline) {
    await _refdata.child("values/valores").once().then((DataSnapshot snap2) {
  List<DataSnapshot> result = snap2.value;
  lista = result
      .map((element) => Item(
          element.key,
          element.value["nome"],
          element.value["preco"].toDouble(),
          element.value["precoantes"] ?? "",
          element.value["tipo"],
          element.value["disponivel"],
          element.value["descricao"],
          element.value["calorias"]))
      .toList();
});

编辑

通过此更改,我能够返回值:

List<Map<dynamic, dynamic>> result =
          List<Map<dynamic, dynamic>>.from(snap2.value);
      result.forEach((element) {
        if (element != null) {
          print(element);
        }
      });

但我无法归还密钥 (1,2,3,4,5)

和这样做是一样的(假设查询按键排序):

List<dynamic> result = snap2.value;
      int _i = 1;
      result.forEach((value) {
        if (value != null) {
          lista.add(Item(
              _i.toString(),
              value["nome"],
              value["preco"].toDouble(),
              value["precoantes"] ?? "",
              value["tipo"],
              value["disponivel"],
              value["descricao"],
              value["calorias"]));
          _i += 1;
          print(value["nome"]);
          print(value);
          print(lista.length);
        }

现在我得到这个错误:

NoSuchMethodError (NoSuchMethodError: The method 'add' was called on null.
Receiver: null
Tried calling: add(Instance of 'Item'))

【问题讨论】:

    标签: firebase dictionary flutter firebase-realtime-database


    【解决方案1】:

    FlutterFire 无法将子节点作为DataSnapshot 对象的列表获取。

    我得到的最接近的是:

    currentRoundListener = dbRoot.child('rounds/$currentRoundKey').once.then((snapshot) {
      currentRound = List<String>.from(snapshot.value as List<dynamic>);
    });
    

    你可以试试:

    List<DataSnapshot> result = List<DataSnashot>.from(snap2.value as List<dynamic>);
    

    但快照下的值更有可能仅作为地图提供:

    Map<String, dynamic> result = Map<String, dynamic>.from(snap2.value as Map<dynamic, dynamic>);
    

    如果您需要维护子节点的顺序,请查看此处:Flutter: Firebase Real-Time database orderByChild has no impact on query result 和此处:Flutter Firebase Database wrong timestamp order

    【讨论】:

    • 对于 List.from 选项我收到此错误:发生异常。 _TypeError(类型 '_InternalLinkedHashMap' 不是类型 'DataSnapshot' 的子类型)
    • 对于 Map 结果 _CastError(类型 'List' 不是类型转换中类型 'Map' 的子类型)
    • 是的,第一个错误是预料之中的,因为客户端只是不暴露孩子DataSnapshots。第二个错误似乎是因为我的代码中有剩余的复制/粘贴,这与你的不同。我更新了我的答案。最后一行应该适合你。我自己用 Map&lt;String, int&gt; 在我有带有数值的按键的地方使用它。
    • 仍然无法使用您的地图实施解决。在下面的答案中,我已经设法在没有钥匙的情况下实现了一些目标。
    【解决方案2】:

    我已经设法使用这个实现来解决它:

    getItems() async {
      String _refOnline;
      List<dynamic> result;
      await _refdata.child("ref").once().then((value) => _refOnline = value.value);
      if (dataRef != _refOnline) {
        await _refdata.child("values/valores").once().then((DataSnapshot snap2) {
          result = snap2.value;
          int _i = 1;
          result.forEach((value) {
            if (value != null) {
              Item _a = Item(
                  _i.toString(),
                  value["nome"],
                  value["preco"].toDouble(),
                  value["precoantes"] ?? "",
                  value["tipo"],
                  value["disponivel"],
                  value["descricao"],
                  value["calorias"]);
              lista.add(_a);
              _i += 1;
            }
          });
          savepref("ref_key", _refOnline);
        });
      } else {
        lista = [oi, oi2, oi3, oi4, oi5, oi6, oi7, oi8, oi9, oi10, oi11, oi12];
        //readIt();
      }
    } 
    

    lista 定义出现问题,阻止它在 lista.add 函数中接收新项目。

    我现在将 lista 定义为:

    List<Item> lista = [];
    

    有了上述功能,现在一切正常。

    谢谢弗兰克·范·普菲伦!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多