我正在尝试使用React/Redux/Firebase进行登录过程,我遇到了一些问题...
我尝试实现Onauthstatatechanged以派遣操作,但它无法正常工作。
它在两种情况下工作:
1-我直接在我的组件中实现了我的onauthstatatechanged:
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));
}
});
};
};
有人可以向我解释为什么它不适用于调度?
谢谢!
两件事:
-
使用一个函数(例如
isUserConnected
),然后将值设置为true
或false
(而不是使用两个不同的函数isUserNotConnected
和isUserConnected
,如您当前是) -
根据firebase文档将
firebaseAuth
更改为firebase.auth()
尝试一下。
(这对我有用)
在Redux(Actions)中:
// 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);
。这是我的根容器中的一个示例,这几乎是我最高的组件
**在您的情况下,您需要将authstatechangelistener移至应用程序级组件,例如componentDidmount()内部。然后将您的疑虑分开,如果存在用户。...然后将函数调用您的操作,以派遣商店更新。
componentDidMount() {
// if redux persist is not active fire startup action
if (!ReduxPersist.active) {
this.props.startup()
}
// ********* Add a listener from the database to monitor whos logged in. *********
firebase.auth().onAuthStateChanged((user) => {
// ********* If a user is logged in firebase will return the user object. THEY ARE NOT LOGGED IN THOUGH *********
if (user) {
console.log('onAuthStateChanged', user)
// ********* Then we call an official Firebase login function through actions *********
this.props.loginRequest(user);
} else {
console.log('No user signed in')
}
});
// ********* After logging in the found user from above we need to set them to redux store *********
let signedInUser = firebase.auth().currentUser;
if (signedInUser) {
this.props.loginRequest(signedInUser);
console.log('currentUserSignedIn', signedInUser)
} else {
console.log('no active user', signedInUser)
}
}
这是我的登录名,它生活在我的动作中
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)
};