【问题标题】:Firebase's set() not working inside onAuthStateChanged()Firebase 的 set() 在 onAuthStateChanged() 中不起作用
【发布时间】:2017-10-17 12:47:53
【问题描述】:

我目前正在使用 Firebase 作为我的数据库,使用 ReactJS 开发我的第一个“大型”网络应用程序。在我遇到这个问题之前,一切都很顺利。

当他们使用 Facebook 或 Twitter 登录应用程序时,我正在尝试保存用户信息,我正在使用 Firebase 提供的方法,如下所示:

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

但是当我尝试将用户登录后保存到数据库中时,什么也没有发生。

这就是我在 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');
                }
            );


        }
    });
}

我尝试将用户保存在另一个功能上,它可以工作,update()set()。但是当我在onAuthStateChanged() 中调用set() 时,它不会。

我的数据库规则是:

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

我错过了什么吗?

谢谢

【问题讨论】:

  • 能不能在用console.log(loggedUser.uid)的set方法之前确认loggedUser.uid不为空
  • @bennygenel 是的,不为空。我只测试了一位用户。我做了一个console.log(loggedUser); 并且 uid 在那里。
  • 你在哪里登录的?在on('value', ....)的回调中?
  • 不,在那之前。设置后this.setState()
  • 请在else语句后检查。因为on(..) 方法是异步的,它可能会失去它的价值。

标签: javascript node.js reactjs firebase firebase-authentication


【解决方案1】:

正如@bennygenel 所建议的,我将lastActivityTime 的值更改为一个简单的字符串,如下所示:

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


            }
        });
    }

现在当用户登录时将其添加到数据库中。我还用once() 更改了on() 方法,因为即使我直接从Firebase 控制台删除,它也在添加用户。

现在要将日期添加到lastActivityItem,我只需将toString() 方法添加到生成的日期,如下所示:

let d = new Date()

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

如果有人知道为什么会这样,请分享。

谢谢@bennygenel !!!

【讨论】:

  • 这是因为new Date 是一个日期对象,您需要对其进行字符串化。你可以使用一些 toString 方法或 getTime 方法
猜你喜欢
  • 2017-04-29
  • 2022-12-18
  • 2021-11-08
  • 2021-04-28
  • 2020-11-15
  • 2016-12-29
  • 2019-05-03
  • 2012-11-09
  • 2011-07-17
相关资源
最近更新 更多