我正在使用Firebase通过Facebook或google处理我的身份验证。我真正不明白的是为什么我的商店没有更新。
下面是我的代码示例:
import { createStore } from 'redux';
import {app, facebookProvider, googleProvider } from './../config/config';
const initialState = {
SCREEN_CURRENT: "login",
authenticated: false
}
const reducer = (state = initialState, action) => {
console.log('reducer', action);
switch(action.type){
case "AUTH_LOGIN_FACEBOOK":
state = {
...state,
authenticated: true
}
app.auth().signInWithPopup(facebookProvider)
.then((user, error) => {
if(error){
console.log("Unable to login with Facebook!");
} else {
console.log("Logged in succesfully");
state = Object.assign({}, state, {
authenticated: true
});
}
}).catch((error) => {
if(error){
console.log("Error from Facebook: " + error.message);
}
});
break;
case "AUTH_LOGIN_GOOGLE":
app.auth().signInWithPopup(googleProvider)
.then((user, error) => {
if(error){
console.log("Unable to login with Google!");
} else {
console.log("Logged in succesfully");
return Object.assign({}, state, {
authenticated: true
});
}
}).catch((error) => {
if(error){
console.log("Error from Google: " + error.message);
}
});
break;
default:
break;
}
return state;
}
const store = createStore(reducer);
store.subscribe(() => {
console.log("Store updated", store.getState());
});
export default store;
即使我成功登录后将身份验证状态更改为true(发生了什么),有人可以向我解释为什么我的商店没有更新吗?
我不明白为什么。
当我单击触发“ AUTH_LOGIN_FACEBOOK”操作的按钮时,商店将得到更新。但是,当我将authenticated的状态更改为true时,不是这样。如何获取商店更新?
答案 0 :(得分:0)
减速器内部逻辑太多。这里要做的第一件事是将它们移至一个动作,一个普通的旧javascript对象,甚至一个函数。请注意,上面的代码没有考虑导入/导出,但是我想您会在这里理解我的意思。因此,您必须使其适应您的用例。
// ##########################################################################
// AUTH FUNCTIONS ###########################################################
// ##########################################################################
const FACEBOOK = 'facebook';
const GOOGLE = 'google';
// just to make sure that you'll always return a valid prodiver.
function getProviderObject(provider) {
return {
[FACEBOOK]: new firebase.auth.FacebookAuthProvider(),
[GOOGLE]: new firebase.auth.GoogleAuthProvider()
}[provider] || null;
}
// this function receives a provider object and return a User, no matter what
// provider, Google or Facebook
function signInWithProvider(provider) {
const providerObject = getProviderObject(provider);
if(!providerObject) {
throw new Error('Invalid provider');
}
try {
const response = await FirebaseApp.auth().signInWithPopup(provider);
return response.user;
} catch(error) {
// handle error...
throw error;
}
}
function signInWithFirebase({ email, password }) {
return FirebaseApp.auth().signInAndRetrieveDataWithEmailAndPassword(email, password);
}
// ##########################################################################
// ACTIONS ##################################################################
// ##########################################################################
// this action acts like a router, which will decide to sign in with an
// external provider (GOOGLE or FACEBOOK) or sign in with email/password
const signIn = param => async dispatch => {
try {
const user = await (
[GOOGLE, FACEBOOK].includes(param) ?
signInWithProvider(param) :
signInWithFirebase(param)
);
dispatch({
type: 'CREATE_SESSION',
payload: user
});
return user;
} catch(error) {
console.log(error);
}
};
// ##########################################################################
// REDUCERS #################################################################
// ##########################################################################
const initialState = {
authenticated: false,
user: null,
// etc...
};
function sessionReducer(state = initialState, action = {}) {
switch(action.type) {
case 'CREATE_SESSION': return {
...action.payload,
authenticated: true,
// whatever props you need here...
};
case 'DESTROY_SESSION': return initialState;
default: return state;
}
}
// ##########################################################################
// EXAMPLE ##################################################################
// ##########################################################################
class Auth extends React.Component {
state = {
email: null,
password: null
};
render() {
const { email, password } = this.state;
return (
<p><a href="#" onClick={this.signInWith(FACEBOOK))>SIGN IN WITH FACEBOOK</a></p>
<p><a href="#" onClick={this.signInWith(GOOGLE))>SIGN IN WITH GOOGLE</a></p>
<form onSubmit={this.onSubmit}>
<input
type="email"
onChange={this.onChange('email')}
value={email} placeholder="Email"
/>
<input
type="password"
onChange={this.onChange('email')}
value={password}
placeholder="Password"
/>
<button>Sign In</button>
</form>
)
}
signInWith = provider => event => {
event.preventDefault();
this.props.signIn(provider);
}
onChange = field => value => this.setState({ [field]: value });
onSubmit = () => {
const { email, password } = this.state;
return this.props.signIn({ email, password });
};
}
export default connect(null, { signIn })(Auth);
我希望这会有所帮助!