Jus*_*ain 9 flutter google-cloud-firestore
我有一类具有几个嵌入式数组以及几个对象的类。我正在使用Flutter,无法弄清楚如何读写Cloud Firestore。
我可以读写默认类型的数据成员,例如String和Int。这是我试图用来从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 = ????
}
Run Code Online (Sandbox Code Playgroud)
在我添加最后3个成员(评分,玩家和gameReview)之前,它一直有效。这应该很明显,但无论如何,它使我难以理解。
救命!
更新:这是Cloud Firestore中存储的文档的示例。这存储在单个文档中。换句话说,我没有为嵌入式对象使用子集合。为了清楚起见,我将其放入JSON格式。我希望这有帮助。
{
"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
}
]
}
Run Code Online (Sandbox Code Playgroud)
更新2:我没有输入整个类的定义,因为我认为如何进行其余的工作对我来说是显而易见的,但是事实并非如此。
我有一个要加载的对象列表。vbandrade的答案是BANG,但是我不太清楚如何创建对象列表。List.from(...)正在寻找迭代器,而不是创建的类。我敢肯定,创建一个新对象然后将其添加到列表中是一种变化,但是我有些困惑。(请参阅上面的类中的编辑,特别是“ itemCounts”成员。
谢谢!!!
vba*_*ade 13
从数组中加载列表,然后让框架进行类型转换。
一个对象就是一个地图,就像您在Json中编写的一样。我也使用命名构造函数。((仍在学习并且不知道如何使用静态构造函数@ganapat提到))
这是工作代码。我保留了Firebase身份验证,并使用了StreamBuilder小部件。
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']);
}
Run Code Online (Sandbox Code Playgroud)
snapshot['itemCount']是一组对象。将数组中的每个项目映射到一个ItemCount对象,并作为List返回:
itemCounts = snapshot['itemCount'].map<ItemCount>((item) {
return ItemCount.fromMap(item);
}).toList();
Run Code Online (Sandbox Code Playgroud)
bha*_*kar 12
如果您因为List<dynamic> is not of type List<someType>从 firestore 读取数据时出错而来到这里,您可以使用List.castFrom
例子:
List<String> cards = List.castFrom(cardsListFromFirebase);
结帐Flutter firebase,List<dynamic> 不是 List<String> 类型
Mor*_*rad 10
您可以使用JsoSerializable()
将以下依赖项添加到 pubspec.yaml
dependencies:
# Your other regular dependencies here
json_annotation: ^2.0.0
dev_dependencies:
# Your other dev_dependencies here
build_runner: ^1.0.0
json_serializable: ^2.0.0
Run Code Online (Sandbox Code Playgroud)
并让你的课程 JsonSerializable()
import 'package:json_annotation/json_annotation.dart';
part 'game.g.dart';
@JsonSerializable()
class GameReview {
String name;
int howPopular;
List<String> reviewers;
GameReview();
factory GameReview.fromJson(Map<String, dynamic> json) => _$GameReviewFromJson(json);
Map<String, dynamic> toJson() => _$GameReviewToJson(this);
}
@JsonSerializable()
class ItemCount {
int itemType;
int count;
ItemCount();
factory ItemCount.fromJson(Map<String, dynamic> json) => _$ItemCountFromJson(json);
Map<String, dynamic> toJson() => _$ItemCountToJson(this);
}
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();
factory GameRecord.fromJson(Map<String, dynamic> json) => _$GameRecordFromJson(json);
Map<String, dynamic> toJson() => _$GameRecordToJson(this);
}
Run Code Online (Sandbox Code Playgroud)
然后通过从终端运行代码生成实用程序来生成 JSON 序列化代码:
flutter packages pub run build_runner build
Run Code Online (Sandbox Code Playgroud)
现在您可以使用 jsonEncode() 和 jsonDecode() 来存储和检索 firestore 中的对象
设置数据:
Firestore.instance
.collection("games")
.document("zZJKQOuuoYVgsyhJJAgc")
.setData(jsonDecode(jsonEncode(gameRecord)));
Run Code Online (Sandbox Code Playgroud)
用于检索数据:
GameRecord.fromJson(jsonDecode(jsonEncode(snapshot.data)));
Run Code Online (Sandbox Code Playgroud)
Firebase 包返回快照中存在的数组/列表类型的列表类型。在分配给变量之前尝试将 List 转换为 List 或 List。对于 GameReview 对象,当前,您正在尝试将 Map 对象分配给该对象,如果您在 GameReview 类中编写静态 fromMap 方法,该方法接受 Map 参数并将其转换为所需的对象结构,那么这将是有益的,正如您在许多中看到的那样颤振示例代码。
class GameReivew{
static GameReivew fromMap(Map<String, dynamic> map){
GameReivew gameReivew = new GameReivew();
gameReivew.name = map["name"];
gameReivew.howPopular = map["howPopular"];
....
return gameReivew;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10475 次 |
| 最近记录: |