Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript firebase返回Napshot承诺_Javascript_Firebase_Callback_Google Cloud Firestore - Fatal编程技术网

Javascript firebase返回Napshot承诺

Javascript firebase返回Napshot承诺,javascript,firebase,callback,google-cloud-firestore,Javascript,Firebase,Callback,Google Cloud Firestore,我正在使用firebase/firestore,我正在寻找一种方法来回报快照的承诺 onlineUsers(){ // i want to return onSnapshot return this.status_database_ref.where('state','==','online').onSnapshot(); } 在另一个文件中,我做了 componentDidMount(){ // this.unsubscribe = this.ref.where

我正在使用firebase/firestore,我正在寻找一种方法来回报快照的承诺

onlineUsers(){
     // i want to return onSnapshot
    return this.status_database_ref.where('state','==','online').onSnapshot();
}
在另一个文件中,我做了

  componentDidMount(){
    // this.unsubscribe = this.ref.where('state','==','online').onSnapshot(this.onCollectionUpdate) 
    firebaseService.onlineUsers().then(e=>{
        console.log(e)
    })
}
我得到了错误

错误:Query.onSnapshot失败:使用无效参数调用

TypeError:\u firebaseService2.default.unsubscribe不是函数

如果我这样做

onlineUsers(){
   return  this.status_database_ref.where('state','==','online').onSnapshot((querySnapshot)=>{
        return querySnapshot
    }) 
}
   this.unsubscribe = firebaseService.onlineUsers().then((querySnapshot)=>{
        console.log(querySnapshot.size)
        this.setState({count:querySnapshot.size})
    })
我明白了

另外,, 当我这样做的时候

onlineUsers(){
   return  this.status_database_ref.where('state','==','online').onSnapshot((querySnapshot)=>{
        return querySnapshot
    }) 
}
   this.unsubscribe = firebaseService.onlineUsers().then((querySnapshot)=>{
        console.log(querySnapshot.size)
        this.setState({count:querySnapshot.size})
    })
//其他文件

 onlineUsers(callback) {
    return this.status_database_ref.where('state', '==', 'online').get()
}
它不会监听更改为firebase,这意味着如果我在firebase中更改,它不会更新或更改大小

----firestore函数--- 我试图使firestore函数在每次更新UserStatus节点时触发,但这需要几秒钟,对我来说很慢

module.exports.onUserStatusChanged = functions.database
.ref('/UserStatus/{uid}').onUpdate((change, context) => {
    // Get the data written to Realtime Database
    const eventStatus = change.after.val();

    // Then use other event data to create a reference to the
    // corresponding Firestore document.
    const userStatusFirestoreRef = firestore.doc(`UserStatus/${context.params.uid}`);


    // It is likely that the Realtime Database change that triggered
    // this event has already been overwritten by a fast change in
    // online / offline status, so we'll re-read the current data
    // and compare the timestamps.
    return change.after.ref.once("value").then((statusSnapshot) => {
        return statusSnapshot.val();
    }).then((status) => {
        console.log(status, eventStatus);
        // If the current timestamp for this data is newer than
        // the data that triggered this event, we exit this function.
        if (status.last_changed > eventStatus.last_changed) return status;

        // Otherwise, we convert the last_changed field to a Date
        eventStatus.last_changed = new Date(eventStatus.last_changed);

        // ... and write it to Firestore.
        //return userStatusFirestoreRef.set(eventStatus);
        return userStatusFirestoreRef.update(eventStatus);
    });
});
用于计算和更新联机用户数的函数

module.exports.countOnlineUsers = functions.firestore.document('/UserStatus/{uid}').onWrite((change, context) => {

    const userOnlineCounterRef = firestore.doc('Counters/onlineUsersCounter');

    const docRef = firestore.collection('UserStatus').where('state', '==', 'online').get().then(e => {
        let count = e.size;
        return userOnlineCounterRef.update({ count })
    })
})

我找到了一个办法

onlineUsers(callback){
   return  this.status_database_ref.where('state','==','online').onSnapshot((querySnapshot)=>{
        callback(querySnapshot.size)
    }) 
}

componentDidMount(){

    this.unsubscribe = firebaseService.onlineUsers(this.onUpdateOnlineUsers);
    console.log(this.unsubscribe)
}
onUpdateOnlineUsers(count){
    this.setState({count})
}
componentWillUnmount(){
    this.unsubscribe();

}

JavaScript中的
Promise
可以只解析(或拒绝)一次。另一方面,
onSnapshot
可以多次给出结果。这就是为什么
onSnapshot
不返回承诺的原因

在您当前的代码中,留给您的是一个挂起的侦听器,它指向
status\u database\u ref
。由于您对数据不做任何处理,因此一直监听数据是浪费时间的

而不是使用
onSnapshot
,:

或者按照您最初的方法:

onlineUsers(){
    return this.status_database_ref.where('state','==','online').get();
}

我知道为时已晚,但这里是我使用TypeScript和Javascript的解决方案

打字稿

JAVASCRIPT(ES5)


弗兰克,我编辑了我的帖子。我按你的方式做了,但它不听firestore的变化。如果我手动将状态更改为脱机,那么我得到的大小不会更改,并且我确实看到它再次调用查询。无论是问题中的代码,还是答案中的代码,都会侦听更改。
onSnapshot
get()
都将立即返回与查询匹配的当前文档。我现在在回答中给出的代码将显示当前在线的用户。现在我还不清楚你的代码想要完成什么(它开始让我感觉像是一个游戏)。我想听听“状态”集合。如果用户注册firebase,它会将其uid状态更改为“在线”,当用户关闭应用程序时,它会更改为“离线”。我想获得当前在线用户的规模。如果应用程序中的用户和其他用户是close应用程序,那么它应该显示真实和更新计数Hey frank,你有什么解决方案吗?你的查询工作正常,但当我在应用程序中,新用户更改为“在线”或“离线”时,计数器不会更改。计数器不能再计算,它不能听变化!此外,我编辑了我的文章,并使用firestore功能进行了编辑,但更新它需要3-5秒,而且速度很慢,我希望我能提供2次投票:一次是正确的解决方案,另一次是用TypeScript给出解决方案!
const _db=firebase.firestore;
const _collectionName="users";

    onDocumentChange = (
    document: string,
    callbackSuccess: (currentData: firebase.firestore.DocumentData, source?: string | 'Local' | 'Server') => void,
    callbackError?: (e: Error) => void,
    callbackCompletion?: () => void
) => {
    this._db.collection(this._collectionName).doc(document).onSnapshot(
        {
            // Listen for document metadata changes
            includeMetadataChanges: true
        },
        (doc) => {
            const source = doc.metadata.hasPendingWrites ? 'Local' : 'Server';
            callbackSuccess(doc.data(), source);
        },
        (error) => callbackError(error),
        () => callbackCompletion()
    );
};
var _this = this;
onDocumentChange = function (document, callbackSuccess, callbackError, callbackCompletion) {
    _this._db.collection(_this._collectionName).doc(document).onSnapshot({
        // Listen for document metadata changes
        includeMetadataChanges: true
    }, function (doc) {
        var source = doc.metadata.hasPendingWrites ? 'Local' : 'Server';
        callbackSuccess(doc.data(), source);
    }, function (error) { return callbackError(error); }, function () { return callbackCompletion(); });
};