Firebase Firestore:离线添加数据后获取文档 ID

the*_*ace 5 javascript offline firebase google-cloud-firestore

我像这样将数据添加到 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)
Run Code Online (Sandbox Code Playgroud)

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

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

Gur*_*uru 10

您甚至可以在本地保存之前获得 Id。你只是用这种方式来写数据。

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

对于 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
          // ...
      }
Run Code Online (Sandbox Code Playgroud)

要检查您是从服务器还是缓存接收数据,请使用快照事件中 SnapshotMetadata 上的 fromCache 属性。如果fromCache 为true,则数据来自缓存并且可能是陈旧的或不完整的。如果 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);
      });
  });
Run Code Online (Sandbox Code Playgroud)

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

 

  });


the*_*ace 0

我遇到了这个适合我的解决方法。

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
        }
      })
    })
Run Code Online (Sandbox Code Playgroud)

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

  1. 我需要订阅所有更改
  2. 我曾经change.doc._document.hasLocalMutations检查它是否是新创建的项目