如何使用 React Redux 实现 Firebase 身份验证?
Posted
技术标签:
【中文标题】如何使用 React Redux 实现 Firebase 身份验证?【英文标题】:How to implement Firebase authentication with React Redux? 【发布时间】:2019-03-25 07:30:12 【问题描述】:我正在使用 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”操作的按钮时,商店会更新。但是,不是当我将身份验证的状态更改为 true 时。如何让商店更新?
【问题讨论】:
【参考方案1】:reducer 内部的逻辑太多了。在这里要做的第一件事是将它们移动到一个动作,或者一个普通的旧 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);
我希望这会有所帮助!
【讨论】:
以上是关于如何使用 React Redux 实现 Firebase 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React、Redux 和 Webpack 实现 Google API
如何使用 Redux 在 React Native 中使用线程调用 API?
如何使用 thunk 和 useDispatch(react-redux 挂钩)从操作中返回承诺?