Firestore 查询,缓慢或返回未定义
Firestore query, slow or returning undefined
我正在尝试检索 2 个查询并在两者之间进行计算。
但它相当慢或返回未定义。
有时它会显示值,但通常是在我刷新应用程序之后。
第一个where,给出字段'active'为真的文档数量。
然后第二部分是检查 active 和 hasread 字段以及 returns 金额。
这是我使用的代码:
export default class Home extends React.Component {
constructor(props) {
super(props)
this.gettingAmount = false;
this.unsubscribe = null;
this.announce = firebase.firestore().collection('announcements');
this.state = {
newAnnouncements: 0,
}
}
componentDidMount() {
this.gettingAmount = true;
let countHasRead;
let countAnnounce;
this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
countAnnounce = snapshot.size;
});
this.announce
.where('active', '==', true)
.where('hasread.' + user.uid, '==', true)
.get()
.then(snapshot => {
countHasRead = snapshot.size;
})
.catch(err => {
console.log('Error getting documents', err);
});
setTimeout(() => {
console.log('second', countAnnounce, countHasRead);
if (this.gettingAmount) {
this.gettingAmount = false;
this.setState({newAnnouncements: countAnnounce - countHasRead});
AsyncStorage.setItem('newAnnouncements', JSON.stringify(countAnnounce - countHasRead));
}
}, 1000);
}
});
}
}
因此 console.log('second')
显示未定义或查询真的很慢并且确实显示了 countAnnounce 和 countHasRead 的值。
是我哪里做错了吗?我不确定为什么它显示为未定义。
请帮忙。
问题不在于查询速度慢,而在于它是异步的。
查看正在发生的事情的一种快速方法是使用一些日志语句:
console.log("Before starting query");
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
console.log("Got query results")
});
console.log("After starting query")
如果您 运行 此代码,它会打印:
Before starting query
After starting query
Got query results
这可能不是您期望的顺序,但这正是应该发生的。由于从 Firestore 加载数据可能需要一些时间,因此该操作在后台进行,而您的其余代码将继续运行。然后当数据加载时,它会用该数据调用你的回调函数,这样你就可以处理它了。
这意味着任何需要从数据库访问数据的代码都必须在回调函数中(从中调用)。
所以在你的情况下,你需要嵌套加载:
if (user) {
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
countAnnounce = snapshot.size;
this.announce
.where('active', '==', true)
.where('hasread.' + user.uid, '==', true)
.get()
.then(snapshot => {
countHasRead = snapshot.size;
console.log('second', countAnnounce, countHasRead);
if (this.gettingAmount) {
this.gettingAmount = false;
this.setState({newAnnouncements: countAnnounce - countHasRead});
AsyncStorage.setItem('newAnnouncements', JSON.stringify(countAnnounce - countHasRead));
}
})
.catch(err => {
console.log('Error getting documents', err);
});
});
}
与问题无关,我建议阅读 Better Arrays in Cloud Firestore! 因为现在有一种更有效的方法来做到这一点:.where('hasread.' + user.uid, '==', true)
需要更少的索引。
我正在尝试检索 2 个查询并在两者之间进行计算。 但它相当慢或返回未定义。
有时它会显示值,但通常是在我刷新应用程序之后。
第一个where,给出字段'active'为真的文档数量。 然后第二部分是检查 active 和 hasread 字段以及 returns 金额。
这是我使用的代码:
export default class Home extends React.Component {
constructor(props) {
super(props)
this.gettingAmount = false;
this.unsubscribe = null;
this.announce = firebase.firestore().collection('announcements');
this.state = {
newAnnouncements: 0,
}
}
componentDidMount() {
this.gettingAmount = true;
let countHasRead;
let countAnnounce;
this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
countAnnounce = snapshot.size;
});
this.announce
.where('active', '==', true)
.where('hasread.' + user.uid, '==', true)
.get()
.then(snapshot => {
countHasRead = snapshot.size;
})
.catch(err => {
console.log('Error getting documents', err);
});
setTimeout(() => {
console.log('second', countAnnounce, countHasRead);
if (this.gettingAmount) {
this.gettingAmount = false;
this.setState({newAnnouncements: countAnnounce - countHasRead});
AsyncStorage.setItem('newAnnouncements', JSON.stringify(countAnnounce - countHasRead));
}
}, 1000);
}
});
}
}
因此 console.log('second')
显示未定义或查询真的很慢并且确实显示了 countAnnounce 和 countHasRead 的值。
是我哪里做错了吗?我不确定为什么它显示为未定义。
请帮忙。
问题不在于查询速度慢,而在于它是异步的。
查看正在发生的事情的一种快速方法是使用一些日志语句:
console.log("Before starting query");
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
console.log("Got query results")
});
console.log("After starting query")
如果您 运行 此代码,它会打印:
Before starting query
After starting query
Got query results
这可能不是您期望的顺序,但这正是应该发生的。由于从 Firestore 加载数据可能需要一些时间,因此该操作在后台进行,而您的其余代码将继续运行。然后当数据加载时,它会用该数据调用你的回调函数,这样你就可以处理它了。
这意味着任何需要从数据库访问数据的代码都必须在回调函数中(从中调用)。
所以在你的情况下,你需要嵌套加载:
if (user) {
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
countAnnounce = snapshot.size;
this.announce
.where('active', '==', true)
.where('hasread.' + user.uid, '==', true)
.get()
.then(snapshot => {
countHasRead = snapshot.size;
console.log('second', countAnnounce, countHasRead);
if (this.gettingAmount) {
this.gettingAmount = false;
this.setState({newAnnouncements: countAnnounce - countHasRead});
AsyncStorage.setItem('newAnnouncements', JSON.stringify(countAnnounce - countHasRead));
}
})
.catch(err => {
console.log('Error getting documents', err);
});
});
}
与问题无关,我建议阅读 Better Arrays in Cloud Firestore! 因为现在有一种更有效的方法来做到这一点:.where('hasread.' + user.uid, '==', true)
需要更少的索引。