简体   繁体   中英

Firebase's set() not working inside onAuthStateChanged()

I'm currently developing my first "big" web app with ReactJS using Firebase as my DB. Everything was going well until I came across with this issue.

I'm trying to save the user info when they log in into the app with Facebook or Twitter, I'm using the methods provided by Firebase like this:

authenticate(option){        

    let provider;

    switch (option) {
        case 'facebook':
            provider = new firebase.auth.FacebookAuthProvider();                
            break;
        case 'twitter':
            provider = new firebase.auth.TwitterAuthProvider();
            break;
        default:
            provider = 'no-provider'
            break;
    }

    if(provider !== 'no-provider'){
        firebase.auth().signInWithPopup(provider).then((result) => {
            console.log("Login with " + provider + " ok!");
            console.log(result);
        }).catch((error) => {
            console.log("Error: there was an error trying to login.");
        });
    }
}

But when I try to save the user into the DB once they've logged in, nothing happens.

This is what I have on App.js

componentDidMount() {
    base.auth().onAuthStateChanged((loggedUser) => {
        if (loggedUser) {
            this.setState({
                userName: loggedUser.displayName,
                userPhoto: loggedUser.photoURL,
                userUID: loggedUser.uid
            });

            base.database().ref('users/' + loggedUser.uid).on('value',
                (user) => {
                    if (user.val() !== null) {
                        if (user.val().votedAlbums !== undefined) {
                            this.setState({
                                votedAlbums: user.val().votedAlbums
                            });
                        }
                    } else {
                        console.log(loggedUser.uid);
                        let userInfo = {
                            lastActivityTime: new Date()
                        }
                        base.database().ref('users/' + loggedUser.uid).set(userInfo).then((ref) =>{
                            console.log(ref); // this logs 'undefined'
                        }).catch((error) => {
                            console.log(error);
                        });
                    }
                },
                (err) => {
                    this.props.history.push('/error');
                }
            );


        }
    });
}

I tried saving the user on another function and it works, both update() and set() . But when I call set() inside onAuthStateChanged() it doesn't.

My DB rules are:

{
  "rules": {
    ".read": true,
    ".write": "auth != null"
  }
}

Am I missing something?

Thanks

As @bennygenel suggested, I changed the value of lastActivityTime to a simple string like this:

componentDidMount() {
        base.auth().onAuthStateChanged((loggedUser) => {
            if (loggedUser) {
                this.setState({
                    userName: loggedUser.displayName,
                    userPhoto: loggedUser.photoURL,
                    userUID: loggedUser.uid
                });

                base.database().ref('users/' + loggedUser.uid).once('value',
                    (user) => {
                        if (user.val() !== null) {
                            if (user.val().votedAlbums !== undefined) {
                                this.setState({
                                    votedAlbums: user.val().votedAlbums
                                });
                            }
                        } else {
                            console.log(loggedUser.uid);

                            let userInfo = {
                                lastActivityTime: "whatever" // replaced new Date() with "whatever"
                            }
                            base.database().ref('users/' + loggedUser.uid).set(userInfo).then((ref) =>{
                                console.log(ref);
                            }).catch((error) => {
                                console.log(error);
                            });
                        }
                    },
                    (err) => {
                        this.props.history.push('/error');
                    }
                );


            }
        });
    }

And now when the user logs in its added to the DB. I also changed the on() method with once() because it was adding the user even if I deleted directly from the Firebase console.

Now to add the date to lastActivityItem I only have to add the toString() method to the generated date like this:

let d = new Date()

let userInfo = {
    lastActivityTime: d.toString()
}

If someone knows why this happened, please share.

Thank you @bennygenel !!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM