Firebase Firestore:离线写入操作的Promise何时会resolve?
问题分析与解决方案
这是Firestore离线模式下的预期行为哦,我之前也碰到过类似的情况,给你拆解一下原因和解决办法:
为什么离线时then()/catch()不触发?
Firestore的离线持久化机制中,当你在离线状态下执行add()这类写操作时,SDK会先把操作缓存到本地,但并不会立刻调用then()或catch()——因为这些回调是用来对应云端操作的完成状态的。只有当设备恢复联网,本地缓存的操作同步到云端成功/失败后,这些回调才会被触发。
不过你可以放心,本地数据其实已经被正确写入离线缓存了,你可以通过指定源为缓存的查询来验证:
db.collection('foo').get({source: 'cache'}) .then(snapshot => { snapshot.forEach(doc => console.log(doc.data())); });
如何在离线时获取本地写入的文档ID?
如果你需要在离线状态下立刻拿到新添加文档的ID,有个实用小技巧:不要用add()方法,而是先手动创建一个带ID的文档引用,再执行set()操作:
// 手动生成文档ID const docRef = db.collection('foo').doc(); // 用set()写入数据 docRef.set({foo: 'bar'}) .then(() => { console.log('Added Foo: ', docRef.id); // 这里在离线状态下也能立刻执行,因为set()针对本地缓存的操作会立即确认 // 后续联网后会自动同步到云端 }) .catch(console.error);
这样不管在线还是离线,then()都会立刻触发,你也能马上拿到文档ID做后续操作。
额外提示:实时监听本地数据变化
如果需要实时感知本地数据的变动,可以用onSnapshot()方法,它能响应本地缓存的更新,离线状态下也能触发:
db.collection('foo').onSnapshot(snapshot => { snapshot.docChanges().forEach(change => { if (change.type === 'added') { console.log('New foo:', change.doc.data()); console.log('Document ID:', change.doc.id); } }); });
内容的提问来源于stack exchange,提问作者themenace
相关产品推荐
相关产品推荐

