Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
150
rated 0 times [  153] [ 3]  / answers: 1 / hits: 16351  / 6 Years ago, tue, april 17, 2018, 12:00:00

I'm using firebase/firestore and I'm looking a way to return promise of snapshot.


onlineUsers(){
// i want to return onSnapshot
return this.status_database_ref.where('state','==','online').onSnapshot();
}

in other file I did


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

I get the errors



Error: Query.onSnapshot failed: Called with invalid arguments.


TypeError: _firebaseService2.default.unsubscribe is not a function



if i do this way


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

I get


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

in addition,
when I do this way


   this.unsubscribe = firebaseService.onlineUsers().then((querySnapshot)=>{
console.log(querySnapshot.size)
this.setState({count:querySnapshot.size})
})

// other file


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

it not listen to change into firebase, means if I change in firebase it's not update or change the size..


---- firestore function ---
I tried to make firestore function that trigger each time the UserStatus node updated but this take some seconds and it slow for me.


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

function to calculate and update count of online users


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

More From » firebase

 Answers
52

A Promise in JavaScript can resolve (or reject) exactly once. A onSnapshot on the other hand can give results multiple times. That's why onSnapshot doesn't return a promise.



In your current code, you're left with a dangling listener to status_database_ref. Since you don't do anything with the data, it is wasteful to keep listening for it.



Instead of using onSnapshot, use get:



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


Or in your original approach:



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

[#54643] Friday, April 13, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
koltenb

Total Points: 276
Total Questions: 92
Total Answers: 101

Location: North Korea
Member since Fri, Nov 4, 2022
2 Years ago
;