firebase 返回快照承诺

新手上路,请多包涵

我正在使用 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 失败:使用无效参数调用。

类型错误:_firebaseService2.default.unsubscribe 不是函数

如果我这样做

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

我得到

TypeError: _firebaseService2.default.onlineUsers(...).then is not a function

另外,当我这样做时

   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 功能 — 我试图使每次 UserStatus 节点更新时触发的 firestore 功能但这需要几秒钟,而且对我来说很慢。

 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 })
    })
})

原文由 Manspof 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 345
2 个回答

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

在您当前的代码中,您留下了 status_database_ref 的悬挂侦听器。由于您不对数据做任何事情,因此继续监听它是一种浪费。

而不是使用 onSnapshot使用 get

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

或者以您原来的方法:

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

原文由 Frank van Puffelen 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

打字稿

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()
    );
};

JavaScript (ES5)

 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(); });
};

原文由 Abhishek Tomar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题