如何在Flutter中使用json_serializable对具有其ID的ID的Firestore文档进行反序列化?

时间:2019-08-15 18:15:08

标签: flutter dart google-cloud-firestore

我的Firestore数据库中有一个简单的Message文档,其中包含一些字段。

enter image description here

我使用json_serializable将其反序列化为对象。我的课如下:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'message_firestore.g.dart';

@JsonSerializable(nullable: true, explicitToJson: true)
class MessageFirestore extends Equatable {
  MessageFirestore(
      this.id, this.content, this.conversationId, this.senderId, this.dateSent);

  factory MessageFirestore.fromJson(Map<String, dynamic> json) =>
      _$MessageFirestoreFromJson(json);

  Map<String, dynamic> toJson() => _$MessageFirestoreToJson(this);

  @JsonKey(name: 'Id')
  final String id;
  @JsonKey(name: 'Content')
  final String content;
  @JsonKey(name: 'ConversationId')
  final String conversationId;
  @JsonKey(name: 'SenderId')
  final String senderId;
  @JsonKey(name: 'DateSent', fromJson: _fromJson, toJson: _toJson)
  final DateTime dateSent;

  static DateTime _fromJson(Timestamp val) =>
      DateTime.fromMillisecondsSinceEpoch(val.millisecondsSinceEpoch);
  static Timestamp _toJson(DateTime time) =>
      Timestamp.fromMillisecondsSinceEpoch(time.millisecondsSinceEpoch);
}

文档中没有名为Id的字段,因此当前未对其ID进行反序列化。 但是,从Firestore检索的地图的key是其ID,因此可以通过手动反序列化地图来读取此值。 我希望在反序列化期间可以访问文档的ID(_b03002 ...)。

是否可以配置json_serializable来读取此ID并将其存储在id属性中?

3 个答案:

答案 0 :(得分:3)

您可以修改fromJson构造函数,以便在第一个参数上提供ID。

factory MessageFirestore.fromJson(String id, Map<String, dynamic> json) {
  return _$MessageFirestoreFromJson(json)..id = id;
}

然后,从您的呼叫者那里看,就像这样

Message(snapshot.documentID, snapshot.data)

答案 1 :(得分:1)

您可以在MessageFirestore类中添加另一个工厂。

  factory MessageFirestore.fromFire(DocumentSnapshot doc) =>
      _$MessageFirestoreFromFire(doc);

之后,您的课堂上将拥有两个工厂功能。

factory MessageFirestore.fromFire(DocumentSnapshot doc) //...

factory MessageFirestore.fromJson(Map<String, dynamic> json) //...

并添加_$MessageFirestoreFromFire(doc)函数,并将_$MessageFirestoreFromJson(json)函数复制到message_firestore.g.dart文件中,并像这样进行编辑:

MessageFirestore _$MessageFirestoreFromFire(DocumentSnapshot doc) {
  return MessageFirestore(
    id: doc.documentID,
    content: doc.data['name'] as String,
    // ... other parameters 
  );
}

在阅读文档时,您可以:

  Stream<List<MessageFirestore>> getMessageList() {
    return Firestore.instance
        .collection('YourCollectionPath')
        .snapshots()
        .map((snapShot) => snapShot.documents
            .map(
              (document) => MessageFirestore.fromFire(document),
            )
            .toList());
  }

简单易用

而且此方法也不会干扰其他使用MessageFirestore实例的类。

祝您今天愉快,希望此方法对您有用。 :)

答案 2 :(得分:0)

改进 Yaobin Then 的帖子:同时删除 toJson 上的 ID:


factory MessageFirestore.fromJson(String id, Map<String, dynamic> json) {
  return _$MessageFirestoreFromJson(json)..id = id;
}

Map<String, dynamic> toJson() {
  var json = _$MessageFirestoreToJson(this);
  json.removeWhere((key, value) => key == 'id');
  return json;
}