繁体   English   中英

Flutter 从 Firebase Cloud Firestore 返回完整数组

[英]Flutter return full arrays from Firebase Cloud Firestore

9 月 2 日最新编辑:

即使有赏金,我也没有得到太多关注,所以我会尝试提出一个更简单、更具体的问题。

因此,我按照下面 Doug 的建议重新组织了数据库,因为我无法在 firebase 中以任何方式引用数组。 所以现在我有一个数组映射,而不仅仅是数组。 像这样:

ObjectsList  >  CarsMap (Map)
                   - sh899873jsa (Array)
                     0  "Toyota"
                     1  "Supra"
                     2  "1996"
                     3  "$4990"

                   - hasd823j399 (Array)
                     0  "Toyota"
                     1  "Corolla"
                     2  "2014"
                     3  "$11990"

                   - nelaoiwi283 (Array)
                     0  "Ford"
                     1  "Territory"
                     2  "2018"
                     3  "$35000"

但我不知道如何实际使用这种结构,因为我以前从未见过这种结构。 我现在收到第一个错误,使用弗兰克在下面的回答中提供给我的代码,我已将其转换为:

 final DocumentReference documents = await Firestore.instance.collection('ObjectsList');
  DocumentSnapshot snapshot = await documents.get();
  Map<String, dynamic> data = snapshot.data;
  var loadCarItems = [];

  data.forEach((k,v) => {
    values = List<String>.from(v as List<String>),
    print(values),
    if (values[0] == "Toyota") {
      loadCarItems.add(values[0]),
    },
  });

  setState(() {
    CarItemsArray = loadCarItems;
  });

但是由于我已更改为 map>array 结构,因此在此行中出现错误:

data.forEach((k,v) => {
  values = List<String>.from(v as List<String>),

错误是:

Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<String>' in type cast

很明显,现在结构已更改,我需要更改此语法,但我不知道如何更改,并且在网上找不到任何内容。

以前的信息:

我正在尝试找出一种从 Firebase 返回整个数组的方法,以便我可以处理内部的数据。

例如,我在数据库中有一个包含数组的文档,如下所示:

ObjectsList  >  sh899873jsa
                   0  "Toyota"
                   1  "Supra"
                   2  "1996"
                   3  "$4990"

                 hasd823j399
                   0  "Toyota"
                   1  "Corolla"
                   2  "2014"
                   3  "$11990"

                  nelaoiwi283
                   0  "Ford"
                   1  "Territory"
                   2  "2018"
                   3  "$35000"

所以对于每个数组,我在创建时生成了一个随机密钥,这并不重要。 我基本上只需要能够将所有数据作为单独的对象返回。 理想情况下,例如,我希望能够返回“所有丰田汽车”。 这就是最后的比赛。

这是我迄今为止根据弗兰克的建议生成的代码,他让我走上了正确的道路。

从构建 wdiget:

          Container(
            child: StreamBuilder(
              stream: Firestore.instance.collection('cars').document('ObjectsList').snapshots(),
              builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
                if (!snapshot.hasData) {
                  return LoadingAnimationBasic();
                }
                if (snapshot.data == null) {
                  return LoadingAnimationBasic();
                } else {
                  return ListView(
                    shrinkWrap: true,
                    children: _buildListCards(snapshot),
                  );
                }
              },
            ),
          ),

_buildListCards 函数经过简化,您可以看到它是如何工作的:

_buildStoresList(AsyncSnapshot<DocumentSnapshot> snapshot) {
return snapshot.data.data.values
    .map((doc) => doc[0] == "Toyota" ? GestureDetector(
  child: Container(
    width: MediaQuery.of(context).size.width,
    child: Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(0.0),
      ),
      color: Colors.white70,
      elevation: 10,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(2.0),
            child: ConstrainedBox(
              constraints: BoxConstraints(
                maxWidth: 120,
                minWidth: 120,
                maxHeight: 100,
                minHeight: 100,
              ),
              child: Image.network(
                'some toyota picture URL',
                fit: BoxFit.cover,
              ),
            ),
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(
                width: MediaQuery.of(context).size.width * 0.5,
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
                  child: Text(
                    doc[1],
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18,
                    ),
                  ),
                ),
              ),
              Container(
                width: MediaQuery.of(context).size.width * 0.5,
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(5, 10, 0, 0),
                  child: Text(
                    doc[2],
                    style: TextStyle(
                      fontSize: 12,
                    ),
                  ),
                ),
              ),
            ],
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(5, 40, 0, 0),
                child: Text(
                  doc[3],
                  style: TextStyle(
                    fontSize: 14,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    ),
  ),
  onTap: () {
    futureTapHandlerHere();
  },
) : SizedBox(), )
    .toList();
}

所以现在唯一剩下的就是能够从数据库中编辑/删除这些条目,我认为这必须依赖于创建它们时生成的唯一标识符。 我不知道如何在没有标识符的情况下执行此功能,但我不知道如何实际使用它,或从数据库中返回它。

调用snapshot.data()返回一个Map<String, dynamic> 您可以遍历此映射中的条目,然后获取每个(数组)值的第一个子项。

所以像这样:

List.from(event.snapshot.value as List)

final DocumentReference documents = await Firestore.instance.collection('cars').document('ObjectsList');
DocumentSnapshot snapshot = await documents.get();
Map<String, dynamic> data = snapshot.data();
var cars = [];
data.forEach((k,v) => {
  var values = List<String>.from(v as List<dynamic>);
  cars.add(values[0]);
})

setState(() {
  arrayOfCars = cars
});

这个问题没有答案。 到目前为止,我仍在苦苦挣扎,并且已经为此损失了 11 天的制作时间。

感谢试图提供帮助的人们的建议,但这最终无济于事,我仍然没有解决它。

以问题中列出的格式执行此操作并没有解决此问题,我正在尝试这种方式,因为另一位用户告诉我,除非它们位于地图下,否则我将无法删除单个数组。

这里的答案是上述情况不正确,解决方案是完全放弃地图而只拥有数组。 我在这里所做的对我来说很有意义是让数组中的第一个对象成为唯一代码,这样我就可以轻松引用它,如下所示:

ObjectsList  >  
(document)      - sh899873jsa (Array)
                 0  "sh899873jsa" 
                 1  "Toyota"
                 2  "Supra"
                 3  "1996"
                 4  "$4990"

               - hasd823j399 (Array)
                 0  "hasd823j399"
                 1  "Toyota"
                 2  "Corolla"
                 3  "2014"
                 4  "$11990"

               - nelaoiwi283 (Array)
                 0  "nelaoiwi283"
                 1  "Ford"
                 2  "Territory"
                 3  "2018"
                 4  "$35000"

然后可以直接引用它们并轻松删除它们:

_deleteMenuItem() async {
  await deleteSelectedImages();
  DocumentReference documentReference = Firestore.instance.collection('data').document('ObjectsList');
  documentReference.updateData({
    CarsMap[selectedItem][0]: FieldValue.delete(),
  });
}

其中 CarsMap 是运行时加载的汽车对象数组,selectedItem 是在 UI 中从 ListTiles 中选择的项目。 因此,第 1 步是从 Firebase 获取所有数据并将其填充到 CarsMap 数组中。 第 2 步是从这个数组构建 ListTiles。 第 3 步是有一个 onTap 方法来选择当前的 ListTile,然后将该 tile 的索引存储到 selectedItem 中。

这完成了我需要它做的事情,用户现在可以根据需要从我的数据库中填充和删除数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM