Reputation: 357
I build react native app and I'm trying to make event when user close the app, so it update in firebase the status to 'offline'. what I do is
import React, { Component } from 'react'
import Router from './src/Router'
import firebase from 'react-native-firebase';
export default class App extends Component {
constructor(props){
super(props)
this.state = {
uid: '',
userStatusDatabaseRef :'',
userStatusFirestoreRef: ''
}
}
componentWillMount() {
firebase.auth().signInAnonymouslyAndRetrieveData().then((user) => {
var uid = firebase.auth().currentUser.uid;
console.log('uid', uid)
var userStatusDatabaseRef = firebase.database().ref('status/' + uid);
var isOfflineForDatabase = {
state: 'offline',
last_changed: firebase.database.ServerValue.TIMESTAMP,
};
var isOnlineForDatabase = {
state: 'online',
last_changed: firebase.database.ServerValue.TIMESTAMP,
};
var userStatusDatabaseRef = firebase.database().ref('status/' + uid);
var userStatusFirestoreRef = firebase.firestore().doc('status/' + uid);
var isOfflineForFirestore = {
state: 'offline',
last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};
var isOnlineForFirestore = {
state: 'online',
last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};
const connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", function (snap) {
// validate if connection is established
if (snap.val() === true) {
// remove the user's record on the disconnect
userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(()=>{
userStatusFirestoreRef.set(isOnlineForFirestore);
})
// then request user to enter their name
} else {
userStatusFirestoreRef.set(isOfflineForFirestore);
}
});
this.setState({userStatusDatabaseRef,userStatusFirestoreRef,uid})
})
}
render() {
return <Router />
}
componentWillUnmount(){
var isOfflineForFirestore = {
state: 'offline',
last_changed: firebase.firestore.FieldValue.serverTimestamp(),
};
this.state.userStatusFirestoreRef.set(isOfflineForFirestore);
}
}
first, I would like to understand when onDisconnect fire and what is do. second, when i navigate to other screen, it fire me and that's not what I'm looking for, only when user close app from each screen. I don't want to duplicate the code and write in each component because it's not right coding. what I'm looking for event from each screen/component that user that can update in firebase offline or online
I changed my code and it update only in firebase and not the firestore
const connectedRef = firebase.database().ref(".info/connected");
// validate if connection is established
if (snap.val() === true) {
userStatusFirestoreRef.set(isOnlineForDatabase);
userStatusDatabaseRef.set(isOnlineForDatabase)
// remove the user's record on the disconnect
userStatusDatabaseRef.onDisconnect().remove((error)=>{
userStatusDatabaseRef.set(isOfflineForFirestore);
userStatusFirestoreRef.set(isOfflineForFirestore);
})
// then request user to enter their name
} else {
userStatusFirestoreRef.set(isOfflineForFirestore);
}
});
why it's not set the value also in firestore to 'offline'
userStatusDatabaseRef.onDisconnect().remove((error)=>{
userStatusDatabaseRef.set(isOfflineForFirestore); // it update only in firebase
userStatusFirestoreRef.set(isOfflineForFirestore);
})
Upvotes: 3
Views: 2117
Reputation: 22209
Once you establish a firebase onDisconnect()
operation, the operation is initiated on FireBase RealTime Sever. It checks if your user can perform write operations and pass callbacks for the same if invalid.
It also checks the connection status. When your connection is lost or timed out or deliberately closed by the client, the connection is invoked.
The second part of your question depends upon the nature of your navigation, whether the component umounts thereby disconnecting from the server or whether it is nested inside the same.
According to the docs , you can use the remove operation
Ensures the data at this location is deleted when the client is disconnected (due to closing the browser, navigating to a new page, or network issues)
YourFireBaseRef.onDisconnect().remove((error) => {
// Do some stuff
});
Also another thing to note is
onDisconnect
operations are only triggered once. If you want an operation to occur each time a disconnect
occurs, you'll need to re-establish the onDisconnect operations each time you reconnect.
Upvotes: 1