我正在尝试检索2个查询并在两个查询之间进行计算。 但这很慢,或者返回未定义。
有时它会显示值,但这通常是在刷新应用程序之后。
第一个,给出字段“ active”为真的文档数量。 然后第二部分是检查active和hasread字段并返回金额。
这是我正在使用的代码:
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的值。
这是我做错了吗?我不确定为什么它显示为未定义。
请帮助。
答案 0 :(得分:1)
问题不仅仅在于查询缓慢,还在于异步。
查看一些正在发生的事情的快速方法是:
console.log("Before starting query");
this.announce
.where('active', '==', true)
.get()
.then(snapshot => {
console.log("Got query results")
});
console.log("After starting query")
如果运行此代码,它将显示:
开始查询之前
开始查询后
获得查询结果
这可能不是您期望的顺序,但这恰恰是应该发生的事情。由于从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)
所需的索引要少得多。