【问题标题】:Flutter firestore - update a single map entry where the key is a urlFlutter firestore - 更新键为 url 的单个地图条目
【发布时间】:2021-01-20 12:01:49
【问题描述】:

如何在键为 url 字符串的映射中更新单个映射条目?

此地图条目是众多地图条目之一。我从 Firestore 检索此地图并将其本地存储在提供程序中。然后用户可以更改此布尔值。

我只想更新已更改的字段。 我的另一个选择是用改变值的新地图覆盖。 我不喜欢这样,因为我不能相信不需要的更改会发生在用户端。

这是我第一次遇到 Firestore 不喜欢所有这些特殊字符的事实。我收到一条使用FieldPath 的消息。我用FieldPath.fromString().toString(),但错误是一样的

路径不得包含“~”、“*”、“/”、“[”或“]”。 '包:cloud_firestore_platform_interface/src/field_path.dart': 断言失败:第 50 行 pos 12: '!path.contains('/')'

产生此错误的代码:

onPressed: () {
  final provider = Provider.of<MaraiMilkProvider>(context, listen: false);
  final user = CurrentUser.getCurrentUser();

  Map<String, dynamic> items = provider.items;

  DocumentReference docRef = FirebaseFirestore.instance.collection(user.uid).doc('newArrivals');

  FirebaseFirestore.instance.runTransaction(
    (tx) async {
      DocumentSnapshot snapshot = await tx.get(docRef);
      Map<String, dynamic> mapUrls = snapshot.get('mapUrls');
      Iterable<String> keys = mapUrls.keys;
      
      // I feel I'm being pedantic here, but I want to make sure I'm not overwriting a malformed url due to unexpected changes on user side.
      for (String key in keys) {
        if (items.keys.contains(key) && items[key] == true) {
          tx.update(docRef, {key: items[key]}); // Am I updating the `mapUrls` field here, or a nonexistent field
        }
      }
    },
  );
},

这会产生异常:

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] 未处理的异常:[cloud_firestore/unknown] java.lang.IllegalArgumentException:使用 FieldPath.of() 用于包含“~*/[]”的字段名.

FieldPath.of() 在 Flutter 中不存在。 FieldPath.fromString() 存在,它返回一个 FieldPath 对象。所以我在上面调用toString() 方法。 从

更改更新行时
tx.update(docRef, {key: items[key]});

tx.update(docRef, {FieldPath.fromString(key).toString(): items[key]});

我明白了

未处理的异常:'package:cloud_firestore_platform_interface/src/field_path.dart':断言失败:第 50 行 pos 12:'!path.contains('/')':路径不得包含 '~'、'*'、 '/'、'[' 或 ']'。

【问题讨论】:

  • 1) 你能给出引发这个错误的代码吗? 2) 你能把这个键的代码显示到数据库吗?
  • 也许您可以以反向索引方式存储值?也就是说,temp 变成了一个对象列表,包含一个字符串值url 和一个布尔值flag。然后,您可以在加载时将列表本地转换为字典。如果这在计算上过于昂贵,您可以从字符串中去除特殊值并将其用作键(假设您不需要重现原始 url)
  • @FrankvanPuffelen 我已经在帖子中添加了代码。至于将这个key写入数据库的代码,我是手动添加的。我仍在构思应用程序的流程。图像的 url 将由所有用户共享,因此我打算在用户注册时添加到初始化过程中。但就目前而言,我仍在试图弄清楚这将如何运作。
  • @MikiMints 如果我理解正确,我想我需要重现该网址。这是所有用户都需要打开或关闭的图像。另外,如果reverse-index 你的意思不是所有项目的映射,我为每个字符串布尔对使用一个映射列表,那么这可能是个好主意。我需要实施并看看它是如何进行的,但我需要我喜欢这个想法。
  • 您能否分享一下数据在 Firestore 中存储时的样子?它可以只是一个示例文档。

标签: firebase flutter google-cloud-firestore


【解决方案1】:

这是一个错误,如果在更新时在键中使用“/”会引发错误,但在使用 set 函数时可以正常工作。 你可以使用

FirebaseFirestore.instance
          .collection('user')
          .doc(docId)
          .set(data, SetOptions(merge: true))

【讨论】:

    猜你喜欢
    • 2020-08-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    相关资源
    最近更新 更多