Manspof
Manspof

Reputation: 357

react native with firebase onDisconnect

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

Answers (1)

Pritish Vaidya
Pritish Vaidya

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

Related Questions