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

查看:113
本文介绍了如何在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个成员(评分,玩家和gameReview).这应该很明显,但无论如何,它使我难以理解.

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",但我不知道该如何创建对象列表. 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对象,并以List的形式返回:

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天全站免登陆