首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我们如何将数据保存在Firestore中的复杂对象中?

我们如何将数据保存在Firestore中的复杂对象中?
EN

Stack Overflow用户
提问于 2022-03-17 07:26:10
回答 2查看 514关注 0票数 1

我使用复杂的对象来管理应用程序中的数据。例如,我有一个由"Defi类“定义的对象(意思是法语中的挑战)。

下面是Defi类:

代码语言:javascript
运行
复制
class Defi {
  final int modeApprentissage;
  final DateTime date;
  final double score;
  final int seconds;
  final List mots;
  final List erreurs;
  final List listes;
  final int langue;
  final int type;
  final int typeMots1;
  final int typeMots2;
  const Defi(
      {required this.modeApprentissage,
      required this.date,
      required this.type,
      required this.langue,
      required this.typeMots1,
      required this.typeMots2,
      required this.score,
      required this.seconds,
      required this.listes,
      required this.mots,
      required this.erreurs});
}

我有一个清单的Defi,我想保存在消防基地FIRESTORE。我的问题是:是否绝对有必要将Defi列表转换为一个映射,以便将其保存在Firestore上?还是有别的办法?

我就是这样做的:

代码语言:javascript
运行
复制
 List _defisMap = [];
    for (Defi def in _defis) {
      _defisMap.add({
        'modeApprentissage': def.modeApprentissage,
        'type': def.type,
        'langue': def.langue,
        'typeMots1': def.typeMots1,
        'typeMots2': def.typeMots2,
        'date': def.date,
        'score': def.score,
        'seconds': def.seconds,
        'listes': def.listes,
        'mots': def.mots,
        'erreurs': def.erreurs,
      });
    }
    if (await _connectivity.checkConnectivity() != ConnectivityResult.none) {
      await FirebaseFirestore.instance
          .collection('familyAccounts')
          .doc(_accountEmail)
          .update({
        'defis': _defisMap,
      });

我在一些文章中读到,在像Defi这样的类中,我可以添加一个“工厂”构造函数?这和我想做的事有关系吗?

我创建了另一个类:

代码语言:javascript
运行
复制
class Classes {
  final String code;
  final String nom;

  const Classes({
    required this.code,
    required this.nom,
  });

  Map<String, dynamic> toJson() => {
        'code': code,
        'nom': nom,
      };


  factory Classes.fromMap(Map data) => Classes(
        code: data['code'] ?? '',
        nom: data['nom'] ?? '',
      );
}

我在Firestore上保存了一个类列表。没问题。但是要检索这个列表:我必须从Firestore上的映射列表转到一个“类”列表。我就是搞不懂语法!

这是我的代码:

代码语言:javascript
运行
复制
final DocumentSnapshot<Map<String, dynamic>> docInfo =
        await FirebaseFirestore.instance
            .collection('familyAccounts')
            .doc(_accountEmail)
            .get();

    _typeCompte =
        docInfo['typeCompte'] == 'prof' ? TypeCompte.prof : TypeCompte.eleve;
    _userId = docInfo['userId'];
    _linked = docInfo['linked'];
    _name = docInfo['name'];
    _avatar = docInfo['avatar'];
    _classe = docInfo['classe'];
    _classeCode = docInfo['classeCode'];
    _country = docInfo['country'];
    _region = docInfo['region'];
    docInfo['langue'] == 'french'
        ? _selectedIoLanguage = Language.french
        : _selectedIoLanguage = Language.english;
    _teacherCode = docInfo['teacherCode'];
    _indexList = docInfo['indexList'];
    _nbrList = docInfo['nbrList'];
    _dateCreationCompte = docInfo['dateCreation'].toDate();
    _defiTemp = docInfo['defis'].toList();

    if (_typeCompte == TypeCompte.prof) {
      _etablissement = docInfo['etablissement'];
      _mesClasses = docInfo['mesClasses'];

(_mesClasses应该是“类”的列表)。

我觉得应该是某种xxx.map()之类的.但我不掌握这个语法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-17 07:58:01

您需要创建toJson方法来将其设置为列表的映射。如果您有Defi类的列表。你可以把它发到地图上。

代码语言:javascript
运行
复制
class Defi {
  final int modeApprentissage;
  final DateTime date;
  final double score;
  final int seconds;
  final List mots;
  final List erreurs;
  final List listes;
  final int langue;
  final int type;
  final int typeMots1;
  final int typeMots2;
  const Defi(
      {required this.modeApprentissage,
      required this.date,
      required this.type,
      required this.langue,
      required this.typeMots1,
      required this.typeMots2,
      required this.score,
      required this.seconds,
      required this.listes,
      required this.mots,
      required this.erreurs});

Map<String, dynamic> toJson() => {
       'modeApprentissage': modeApprentissage,
        'type': type,
        'langue': langue,
        'typeMots1': typeMots1,
        'typeMots2': typeMots2,
        'date': date,
        'score': score,
        'seconds': seconds,
        'listes': listes,
        'mots': mots,
        'erreurs': erreurs,
      };
}

您的列表名应该是List<Defi> _defis,然后用toJson映射它。var jsonMap = _defisMap.map((e) => e.toJson()).toList();

代码语言:javascript
运行
复制
var jsonMap = _defis.map((e) => e.toJson()).toList();

if (await _connectivity.checkConnectivity() != ConnectivityResult.none) {
      await FirebaseFirestore.instance
          .collection('familyAccounts')
          .doc(_accountEmail)
          .update({
        'defis': jsonMap,
      });

您还可以使用fromJson方法从api调用映射它。这条路。将其添加到Defi类中。

代码语言:javascript
运行
复制
factory Defi.fromJson(Map<String, dynamic> json) {
    return Defi(
        modeApprentissage: json['modeApprentissage'],
        type: json['type'],
        langue: json['langue'],
        typeMots1: json['typeMots1'],
        typeMots2: json['typeMots2'],
        date: json['date'],
        score: json['score'],
        seconds: json['seconds'],
        listes: json['listes'],
        mots: json['mots'],
        erreurs: json['erreurs'],);
  }

当您调用api时,您需要调用该函数。

代码语言:javascript
运行
复制
final Map<String, dynamic> jsonResult = json.decode(response.body);


//if it is a list returning from api. You can change variables what you got from api.


(jsonResult as List<dynamic>)
          .map((data) => Defi.fromJson(data))
          .toList();

// if it is not list 

Defi.fromJson(jsonResult);
票数 3
EN

Stack Overflow用户

发布于 2022-03-17 08:03:45

是的,转换成地图是绝对必要的。Firestore是一个文档存储,文档的定义是一个json对象,它用Dart表示。但是,你不需要“手动”去做。我们大多数人都使用包来为我们完成映射。

冻住JsonSerializable,然后我们简单地调用.toJson并将其传递给函数。此外,如果您知道集合存储的是什么类型的话,那么Firestore现在就支持.withConverter函数了,所以您不需要进行任何转换。

因此,如果您知道集合的类型是Defi,您可以这样做。

代码语言:javascript
运行
复制
   final defyCollection = FirebaseFirestore.instance.collection('defis').withConverter<Defi>(
        fromFirestore: (snapshot, _) {
          final data = snapshot.data()!;
          data['id'] = snapshot.id;
          return Defi.fromJson(data);
        },
        toFirestore: (object, _) => object.toJson(),
      )

这样,您就可以简单地使用defyCollection,数据属性或函数将被键入到您的类型中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71508427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档