2

我的用例是我有一个<iron-form>带有单个<paper-textarea>字段的字段,该字段接受我解析为数组的电子邮件地址字符串列表,然后我想:

  1. 将各个电子邮件地址存储在我的 Firebase 中(用于索引和查找目的),
  2. 在多个位置(每个数据扇出技术),
  3. 使用单个写入操作(因为如果列表那么长,我不想进行 100 次 API 调用)和
  4. 不覆盖任何现有数据。

具体来说,我想从状态A开始,如下:

状态 A
my-app
 |
 - emails
 |  |
 |  - email1@example,com
 |     |- old: "data"
 |  - email2@example,com
 |     |- old: "data"
 - users
    |
    - c0djhbQi6vc4YMB-fDgJ

并达到如下状态B:

状态 B
my-app
 |
 - emails
 |  |
 |  - email1@example,com
 |     |- old: "data"
 |  - email2@example,com
 |     |- old: "data"
 |  - email3@example,com
 |     |- new: "data"
 |  - email4@example,com
 |     |- new: "data"
 - users
    |
    - c0djhbQi6vc4YMB-fDgJ
       |
       - emails
          |
          - email3@example,com
             |- new: "data"
          - email4@example,com
             |- new: "data"

注意:{old: "data"}不会被覆盖。

背景

我寻求扩展这个 SO 问题和答案

在那里,我们使用三个选项在新位置插入了一个节点:

  1. 使用firebase-query
  2. JS SDK
  3. 使用firebase-document

现在,我需要为多个节点(使用用户定义的而非自动生成的密钥;即,密钥是特定的电子邮件地址)执行相同类型的插入(不删除或替换旧数据)。我还需要使用数据扇出技术通过单个写入操作更新多个路径。

类似于此处显示的内容

https://firebase.google.com/docs/database/web/read-and-write#update_specific_fields
function writeNewPost(uid, username, picture, title, body) {
  // A post entry.
  var postData = {
    author: username,
    uid: uid,
    body: body,
    title: title,
    starCount: 0,
    authorPic: picture
  };

  // Get a key for a new Post.
  var newPostKey = firebase.database().ref().child('posts').push().key;
  // * * * * * * * * * * * * * * * *  
  // THE ABOVE LINE NEEDS TO CHANGE TO SUPPORT USER-GENERATED KEYS SUCH AS EMAIL ADDRESSES
  // * * * * * * * * * * * * * * * * 

  // Write the new post's data simultaneously in the posts list and the user's post list.
  var updates = {};
  updates['/posts/' + newPostKey] = postData;
  updates['/user-posts/' + uid + '/' + newPostKey] = postData;

  return firebase.database().ref().update(updates);
}

另请注意,其中一条评论提到:

上面没有理由newPostKey不能是电子邮件地址...

挑战在于我需要在一次调用中同时将多个密钥写入多个位置。

4

1 回答 1

3

Firebase 实时数据库支持任意复杂的原子深度更新(博客文章)。它是这样工作的:

  1. .update()您可以通过一次调用更新任意深度的路径
  2. 更新映射键侧的完整路径将被替换,因此如果您不想吹走父级,则必须直接寻址子键
  3. 路径是相对于您当前的参考

因此,让我们以您的示例为例:

var update = {};

update['emails/email3@example,com'] = {new: 'data'};
update['emails/email4@example,com'] = {new: 'data'};
update['users/c0djhbQi6vc4YMB-fDgJ/emails/email3@example,com'] = {new: 'data'};
update['users/c0djhbQi6vc4YMB-fDgJ/emails/email4@example,com'] = {new: 'data'};

firebase.database().ref().update(update);

这将同时更新所有位置。要使其动态化,只需在构造键时使用字符串插值。

于 2016-11-28T01:38:34.820 回答