Firestore查询,速度缓慢或返回未定义

时间:2019-01-09 13:47:50

标签: react-native google-cloud-firestore react-native-firebase

我正在尝试检索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的值。

这是我做错了吗?我不确定为什么它显示为未定义。

请帮助。

1 个答案:

答案 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)所需的索引要少得多。