【问题标题】:Firebase Firestore: get document ID after adding data offlineFirebase Firestore:离线添加数据后获取文档ID
【发布时间】:2018-09-24 13:32:29
【问题描述】:

我像这样向 Firestore 添加数据:

db
    .collection('foo')
    .add({foo: 'bar'})
    .then(docRef => {
      console.log('Added Foo: ', docRef.id)
      // do some stuff here with the newly created foo and it's id.
    })
    .catch(console.error)

创建文档后,我想使用新文档或特别是它的 ID。文档以有效 ID 存储在本地数据库中。

但是如何在文档创建后获取 ID?在数据与服务器同步之前,promise 不会被解析。

【问题讨论】:

  • 我没有看到这里的问题。你想用 id 做点什么,所以在写着// do some stuff here with the newly created foo and it's id.的部分做。
  • @DavidKnipe 只要你离线运行,这部分就永远不会执行
  • Dennis 您是否找到了解决此问题的好方法或解决方法,在需要离线且需要这些 id 来保存子数据的混合应用程序上易于/最佳实施?
  • @moplin 是的,请看下面我自己的答案

标签: javascript firebase google-cloud-firestore offline


【解决方案1】:

您甚至可以在本地保存之前获取 Id。你就用这种方式写数据吧。

      // Add a new document with a generated id.
     var newCityRef = db.collection("cities").doc();
      var id = newCityRef.key;
      // later...
       newCityRef.set(data);

对于 Web,默认情况下禁用离线持久性。要启用持久性,请调用 enablePersistence 方法

firebase.firestore().enablePersistence()
  .then(function() {
      // Initialize Cloud Firestore through firebase
      var db = firebase.firestore();
  })
  .catch(function(err) {
      if (err.code == 'failed-precondition') {
          // Multiple tabs open, persistence can only be enabled
          // in one tab at a a time.
          // ...
      } else if (err.code == 'unimplemented') {
          // The current browser does not support all of the
          // features required to enable persistence
          // ...
      }

要检查您是从服务器还是从缓存接收数据,请在快照事件中使用 SnapshotMetadata 的 fromCache 属性。如果fromCache 为真,则数据来自缓存并且可能是陈旧的或不完整的。如果 fromCache 为 false,则数据是完整的,并且是服务器上最新更新的最新数据。

默认情况下,如果仅 SnapshotMetadata 发生更改,则不会引发任何事件。如果您依赖 fromCache 值,请在附加侦听处理程序时指定 includeMetadataChanges 侦听选项。

db.collection("cities").where("state", "==", "CA")
  .onSnapshot({ includeQueryMetadataChanges: true }, function(snapshot) {
      snapshot.docChanges.forEach(function(change) {
          if (change.type === "added") {
              console.log("New city: ", change.doc.data());
          }

          var source = snapshot.metadata.fromCache ? "local cache" : "server";
          console.log("Data came from " + source);
      });
  });

因此,如果您添加新数据并且启用了离线功能,您的数据将被添加到缓存中,并且可以被侦听器侦听。

 

  });

【讨论】:

  • 好的。这给了我对象的 ID。但这对我来说没有用,直到对象存在于本地数据库中并且这是异步完成的。我仍然没有看到任何其他方法,然后使用下面的解决方法。
  • 我现在已经在我的回答中说明了离线功能。因此,每当您添加新数据时,它都会被添加到缓存中,您可以在任何地方使用它,当您连接回互联网时,它将被写入服务器。
  • 我启用了离线持久性。如何启用它是毫无疑问的。我确实知道缓存和服务器之间的区别,但在这种情况下并不重要。我的问题是:“有没有比我下面的解决方法更好的解决方案,由于上述原因,我发现在创建对象后获取对象及其 ID 不是最理想的?”。我不知道还能怎么说。
【解决方案2】:

我遇到了这个对我有用的解决方法。

db
    .collection('foo')
    .where('fooCreator', '==', currentUserId)
    .onSnapshot(querySnapshot => {
      querySnapshot.docChanges.forEach(change => {
        if (change.type === 'added' && change.doc._document.hasLocalMutations) {
          const fooId = change.doc.id
          const foo = change.doc.data()
          // do something with foo and fooId
        }
      })
    })

它有效,但我不太喜欢它,因为:

  1. 我需要订阅所有更改
  2. 我使用change.doc._document.hasLocalMutations来检查它是否是一个新创建的项目

【讨论】:

    猜你喜欢
    • 2020-12-04
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2018-07-22
    • 2022-07-01
    • 2019-03-09
    相关资源
    最近更新 更多