我正在使用Firestore的Web API来执行一个简单查询,该查询是根据日期属性设置为字符串格式('2017-12-30')的。我使用onSnapshot()方法作为侦听器订阅文档更改。结果列表的初始填充按预期工作-顺序正确。
当我对数据进行更改时,然后以更改类型“ modified”调用回调。如果有任何更改影响date属性,那么我将无法对结果列表中的项目进行重新排序-与旧的实时数据库不同。也就是说,直到我看到DocumentChange的newIndex和oldIndex属性。它们未针对Web API(https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentChange)进行记录,但已作为Node.js API(https://cloud.google.com/nodejs/docs/reference/firestore/0.10.x/DocumentChange)的一部分进行记录。
因此,我的问题似乎已得到解决-除了在实践中newIndex和oldIndex中的值似乎在很大程度上是随机的,并且如果刷新查询与实际顺序无关。我无法找出任何可以解释我返回的索引值的模式。
有人成功使用过DocumentChange.newIndex和DocumentChange.oldIndex吗?如果没有,您将如何更改订购结果以重新订购?
const query = firestore.collection(`users/${uid}/things`).
orderBy('sortDate', 'desc').limit(1000)
query.onSnapshot(snapshot => {
snapshot.docChanges.forEach(change => {
if (change.type === "added") {
dispatch(addThing({
id: change.doc.id,
...change.doc.data()
}, change.newIndex)
}
if (change.type === "modified") {
dispatch(changeThing({
id: change.doc.id,
...change.doc.data()
}, change.oldIndex, change.newIndex))
}
if (change.type === "removed") {
dispatch(removeThing(change.doc.id, change.oldIndex))
}
})
})
最佳答案
我使用DocumentChange索引的最初问题是由于代码中其他地方的一些错误。由于在Node.js Firestore文档之外没有找到任何使用此示例的示例,因此这是我用来验证其正确行为(ES6)的测试代码。假定firebase
已被初始化。
cleanTestData = (firestore, path) => {
console.log("Cleaning-up old test data")
var query = firestore.collection(path)
return query.get().then(snapshot => {
const deletePromises = []
if (snapshot.size > 0) {
snapshot.docs.forEach(function(doc) {
deletePromises.push(doc.ref.delete().then(() => {
console.log("Deleted ", doc.id)
}))
});
}
return Promise.all(deletePromises)
}).then(() => {
console.log("Old test data cleaned-up")
})
}
createTestData = (firestore, path) => {
console.log("Creating test data")
const batch = firestore.batch()
const data = {
a: '2017-09-02',
b: '2017-12-25',
c: '2017-10-06',
d: '2017-08-02',
e: '2017-09-20',
f: '2017-11-17'
}
for (const id in data) {
batch.set(firestore.collection(path).doc(id), { date: data[id] })
}
return batch.commit().then(() => {
console.log("Test data created");
}).catch(error => {
console.error("Failed to create test data: ", error);
})
}
subscribe = (firestore, path) => {
const datesArray = []
return firestore.collection(path).orderBy('date', 'asc').onSnapshot(snapshot => {
snapshot.docChanges.forEach(change => {
console.log(change.type, "id:", change.doc.id,
"; date:", change.doc.data().date,
"; oldIndex:", change.oldIndex, "; newIndex:", change.newIndex,
"; metadata: ", change.doc.metadata)
if (change.oldIndex !== -1) {
datesArray.splice(change.oldIndex, 1);
}
if (change.newIndex !== -1) {
datesArray.splice(change.newIndex, 0, change.doc.data().date);
}
console.log(" -->", JSON.stringify(datesArray))
})
})
}
update = (firestore, path) => {
console.log("Updating test data")
return firestore.collection(path).doc('d').set({date: '2018-01-02'}).then(() => {
console.log("Test doc 'd' updated from '2017-08-02' to '2018-01-02'")
})
}
query = (firestore, path) => {
var query = firestore.collection(path).orderBy('date', 'asc')
return query.get().then(snapshot => {
const dates = []
if (snapshot.size > 0) {
snapshot.docs.forEach(function(doc) {
dates.push(doc.data().date)
});
}
console.log("Fresh query of data: \n -->", JSON.stringify(dates))
})
}
handleStartTest = e => {
console.log("Starting test")
const firestore = firebase.firestore()
const path = `things`
let unsubscribeFn = null
unsubscribeFn = this.subscribe(firestore, path)
this.cleanTestData(firestore, path).then(() => {
return this.createTestData(firestore, path)
}).then(() => {
return this.update(firestore, path)
}).then(() => {
return this.query(firestore, path)
}).then(() => {
unsubscribeFn()
console.log("Test complete")
}).catch((error) => {
console.error("Test failed: ", error)
})
}
关于javascript - 如何使用DocumentChange.newIndex重新排序Firestore“已修改”的更改?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48034302/