你如何在 Flutter 中从 Cloud Firestore 加载数组和对象 [英] How do you load array and object from Cloud Firestore in Flutter

查看:26
本文介绍了你如何在 Flutter 中从 Cloud Firestore 加载数组和对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个嵌入式数组和几个对象的类.我正在使用 Flutter,但不知道如何读取/写入 Cloud Firestore.

I have a class that has several embedded arrays as well as a couple of objects. I'm using Flutter and can't figure out how to read/write to Cloud Firestore.

我可以读/写默认类型的数据成员,比如 String 和 Int.这是我试图用来从 DocumentSnapshot 实例化对象的构造函数:

I can read/write data members that are default types like String and Int. Here is the constructor I'm trying to use to instantiate an object from a DocumentSnapshot:

 class GameReview {
   String name;
   int howPopular;
   List<String> reviewers;
 }

 class ItemCount {
   int itemType;
   int count;

   ItemCount.fromMap(Map<dynamic, dynamic> data)
       : itemType = data['itemType'],
         count = data['count'];
 }

 class GameRecord {
   // Header members
   String documentID;
   String name;
   int creationTimestamp;
   List<int> ratings = new List<int>();
   List<String> players = new List<String>();
   GameReview gameReview;
   List<ItemCount> itemCounts = new List<ItemCount>();

   GameRecord.fromSnapshot(DocumentSnapshot snapshot)
       : documentID = snapshot.documentID,
         name = snapshot['name'],
         creationTimestamp = snapshot['creationTimestamp'],
         ratings = snapshot['ratings'], // ERROR on run
         players = snapshot['players'], // ERROR on run
         gameReview = snapshot['gameReview']; // ERROR on run
         itemCount = ????
 }

在我添加最后 3 个成员(评分、玩家和游戏评论)之前,它一直有效.这应该是显而易见的,但无论如何,它让我望而却步.

It works until I add the last 3 members (ratings, players and gameReview). This should be obvious but none the less, it eludes me.

帮助!

更新:以下是存储在 Cloud Firestore 中的文档示例.这存储在单个文档中.换句话说,我没有为嵌入的对象使用子集合.为清楚起见,我将其放入 JSON 格式.我希望这会有所帮助.

UPDATE: Here is a sample of the document stored in Cloud Firestore. This is stored in a single document. In other words, I'm not using sub-collections for the embedded objects. I put it into a JSON format for clarity. I hope this helps.

 {
   "documentID": "asd8didjeurkff3",
   "name": "My Game Record",
   "creationTimestamp": 1235434,
   "ratings": [
     4,
     2012,
     4
   ],
   "players": [
     "Fred",
     "Sue",
     "John"
   ],
   "gameReview": {
     "name": "Review 1",
     "howPopular": 5,
     "reviewers": [
       "Bob",
       "Hanna",
       "George"
     ]
   },
  "itemCounts": [
     {
       "itemType": 2,
       "count": 3
     },
     {
       "itemType": 1,
       "count": 2
     }
   ]
 }

更新2:我没有输入整个类的定义,因为我认为如何做其余的事情对我来说很明显,但可惜事实并非如此.

UPDATE 2: I didn't put in the whole class definition because I thought it would be obvious to me how to do the rest but alas that was not the case.

我有一个我想加载的对象列表.vbandrade 的回答是 BANG on,但我不太清楚我应该如何创建对象列表.List.from(...) 正在寻找迭代器,而不是创建的类.我确定这是创建一个新对象然后将其添加到列表中的一些变体,但我有点困惑.(参见上面类中的编辑,特别是itemCounts"成员.

I have a list of objects that I want to load.vbandrade's answer is BANG on but I can't quite figure out how I'm supposed to create the list of objects. List.from(...) is looking for an iterator, not a created class. I'm sure it's some variation of creating a new object and then adding it to a list but I'm a little confused. (see edits in class above, specifically, the "itemCounts" member.

推荐答案

从数组中加载列表并让框架处理类型转换.

load the list from the array and let the framework take care of type casting.

一个对象只是一张地图,就像你在你的 Json 中写的那样.我也使用命名构造函数.((仍在学习,不知道如何使用提到的静态构造函数@ganapat))

an object is simply a map, like you wrote in your Json. I also use named constructor. ((still learning and dont know how to use the static constructor @ganapat mentioned))

这是工作代码.我保留了 Firebase 身份验证并使用了 StreamBuilder 小部件.

here´s the working code. I kept firebase auth out and used the StreamBuilder widget.

import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'model/firebase_auth_service.dart';

void main() async {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  final firebaseAuth = new FirebaseAuthService();

  MyApp() {
    firebaseAuth.anonymousLogin();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Center(
                child: FlatButton(
      color: Colors.amber,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text("get Game Record"),
          StreamBuilder<GameRecord>(
            stream: getGame(),
            builder: (BuildContext c, AsyncSnapshot<GameRecord> data) {
              if (data?.data == null) return Text("Error");

              GameRecord r = data.data;

              return Text("${r.creationTimestamp} + ${r.name}");
            },
          ),
        ],
      ),
      onPressed: () {
        getGame();
      },
    ))));
  }
}

Stream<GameRecord> getGame() {
  return Firestore.instance
      .collection("games")
      .document("zZJKQOuuoYVgsyhJJAgc")
      .get()
      .then((snapshot) {
    try {
      return GameRecord.fromSnapshot(snapshot);
    } catch (e) {
      print(e);
      return null;
    }
  }).asStream();
}

class GameReview {
  String name;
  int howPopular;
  List<String> reviewers;

  GameReview.fromMap(Map<dynamic, dynamic> data)
      : name = data["name"],
        howPopular = data["howPopular"],
        reviewers = List.from(data['reviewers']);
}

class GameRecord {
  // Header members
  String documentID;
  String name;
  int creationTimestamp;
  List<int> ratings = new List<int>();
  List<String> players = new List<String>();
  GameReview gameReview;

  GameRecord.fromSnapshot(DocumentSnapshot snapshot)
      : documentID = snapshot.documentID,
        name = snapshot['name'],
        creationTimestamp = snapshot['creationTimestamp'],
        ratings = List.from(snapshot['ratings']),
        players = List.from(snapshot['players']),
        gameReview = GameReview.fromMap(snapshot['gameReview']);
}

snapshot['itemCount'] 是一个对象数组.将该数组中的每个项目映射到一个 ItemCount 对象并作为列表返回:

snapshot['itemCount'] is an array of objects. map each item in that array to an ItemCount object and return as a List:

    itemCounts = snapshot['itemCount'].map<ItemCount>((item) {
      return ItemCount.fromMap(item);
    }).toList();

这篇关于你如何在 Flutter 中从 Cloud Firestore 加载数组和对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆