React Native / Redux / Firebase - 未调度onAuthStateChanged

时间:2017-12-17 01:18:11

标签: firebase react-native react-redux react-thunk

我正在尝试使用react native / redux / firebase进行登录,我遇到了一些问题......

我尝试实现onAuthStateChanged来调度一个动作,但是它没有按照我想要的那样工作。

它适用于两种情况:

1 - 我直接在我的组件中实现了onAuthStateChanged,如下所示:

componentDidMount() {
    firebaseAuth.onAuthStateChanged()
        .then((user) => {
            if (user) {
                Actions.home();
            } else {
                Actions.login();
            }
        });
}

2 - 我将它作为一个带有redux-thunk但没有调度的动作实现(但是我不能发送一个动作并重定向到我正确的路径)

export const isAuthenticated = () => {
    firebaseAuth.onAuthStateChanged()
        .then((user) => {
            if (user) {
                console.log("launch.action#isAuthenticated - user already connected");
            } else {
                console.log("launch.action#isAuthenticated - user not connected");
            }
        });

};

我想做的就是这个(但不起作用):

export const isAuthenticated = () => {
return (dispatch) => {
    firebaseAuth.onAuthStateChanged()
        .then((user) => {
            console.log('user', user);
            if (user) {
                console.log("launch.action#isAuthenticated - user already connected");
                dispatch(isUserConnected(true));
            } else {
                console.log("launch.action#isAuthenticated - user not connected");
                dispatch(isUserNotConnected(true));
            }
        });
};

};

有人可以解释一下为什么它不适用于发送?

谢谢!

2 个答案:

答案 0 :(得分:1)

两件事:

  1. 使用一个函数(例如isUserConnected)并将值设置为truefalse(而不是使用两个不同的函数isUserNotConnectedisUserConnected,就像你现在的那样)

  2. 根据firebase documentation

  3. firebaseAuth更改为firebase.auth()

    试试这个。

    (这对我有用)

    在Redux中(操作):

    // Firebase
    import firebase from 'firebase';
    
    // Redux Function
    export const testFirebaseInRedux = () => {
      return (dispatch, getState) => {
        firebase.auth().onAuthStateChanged(function (user) {
          if (user) {
            console.log("testFirebaseInRedux: logged in");
            dispatch(isUserConnected(true));
          } else {
            console.log("testFirebaseInRedux: not logged in");
            dispatch(isUserConnected(false));
          }
        })
      }
    }
    
    export const isUserConnected = (payloadToSet) => {
      return {
        type: 'IS_USER_CONNECTED',
        payload: payloadToSet
      }
    }
    

    在Redux中(缩减器):

    export default function (state=initialState, action) {
      switch(action.type) {
      case 'IS_USER_CONNECTED':
        return {
          ...state,
          isUserConnected: action.payload
        }
      default:
        return {
            ...state
        }
      }
    }
    

    <强>组件:

    // Libraries
    import React from 'react';
    
    // Redux
    import {connect} from 'react-redux';
    import {bindActionCreators} from 'redux';
    import {testFirebaseInRedux} from './../actions/index.js';
    
    class YourComponent extends React.Component {
      constructor(props) {
        super(props);
      }
    
      componentDidMount() {
        this.props.testFirebaseInRedux()
      }
    
    }
    
    function mapStateToProps(state) {
        return {
          user: state.user
        };
    }
    
    function matchDispatchToProps(dispatch) {
        return bindActionCreators({
          testFirebaseInRedux: testFirebaseInRedux,
        }, dispatch)
    }
    
    
    export default connect(mapStateToProps, matchDispatchToProps)(YourComponent);
    

答案 1 :(得分:0)

。这是我的Root容器中的一个示例,它几乎是我的最高组件

**在您的情况下您需要将authStateChangeListener移动到应用程序级别组件,就像在componentDidMount()中一样。然后,如果用户存在,请将您的问题分开....然后从调度商店更新的操作中调用函数。

export const loginRequest = user => dispatch => {
    // ******** This gets called in RootContainer on mount, it will populate redux store with the entire User object from firebase ********
    // ******** FYI - The entire user object also contains their vehicles ********
    // ******** Here we need to check if user already exists in Firebase Database so that we dont overwrite their old data ********
    // ******** WARNING! With Firebase if you set data to a spot that has existing data it will overwrite it! ********
    console.log('RECIEVED USER TO LOOKUP', user);
    firebase.database().ref('users/' + user.uid).once('value').then(function (snapshot) {
        // ******** This method is straight from their docs ********
        // ******** It returns whatever is found at the path xxxxx/users/user.uid ********
        let username = snapshot.val();
        console.log(' FOUND THIS USER FROM THE DB', username);
        {
            // ******** If the username object is empty there wasn't any data at xxxxxx/user/user.uid ********
            // ******** It's safe to write data to this spot ********
            username === null ? firebase.database().ref('users/' + user.uid).set({
                account: username
            }).then(function () {
                console.log('STORED THIS USER TO FIREBASE DB', username);
                dispatch(userSet(username))
            })
                // ******** Otherwise, the user already exists and we should update redux store with logged in user ********
                : dispatch(userSet(username))
        }
    })
        .catch((err) => console.log(err));

    dispatch(userSet(user))
    console.log('INSIDE FIREBASEE DB SET', user)

};

}

这是我的loginRequest,它存在于我的行动中

bool