如何在Redux传奇中处理Firebase身份状态观察器?
firebase.auth().onAuthStateChanged((user) => {
});
我想在我的应用启动时运行APP_START
传奇,它将运行firebase.auth().onAuthStateChanged
观察者,并根据回调运行其他sagas。
据我了解, eventChannel 是正确的方法。但是我不知道如何使其与firebase.auth().onAuthStateChanged
一起使用。
有人可以显示如何将firebase.auth().onAuthStateChanged
放入eventChannel吗?
答案 0 :(得分:3)
您可以使用eventChannel。这是示例代码:
function getAuthChannel() {
if (!this.authChannel) {
this.authChannel = eventChannel(emit => {
const unsubscribe = firebase.auth().onAuthStateChanged(user => emit({ user }));
return unsubscribe;
});
}
return this.authChannel;
}
function* watchForFirebaseAuth() {
...
// This is where you wait for a callback from firebase
const channel = yield call(getAuthChannel);
const result = yield take(channel);
// result is what you pass to the emit function. In this case, it's an object like { user: { name: 'xyz' } }
...
}
完成后,您可以使用this.authChannel.close()
关闭频道。
答案 1 :(得分:0)
创建自己的函数onAuthStateChanged()
,该函数将返回Promise
function onAuthStateChanged() {
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
resolve(user);
} else {
reject(new Error('Ops!'));
}
});
});
}
然后使用call方法同步获取user
const user = yield call(onAuthStateChanged);
答案 2 :(得分:0)
这可以在Saga中进行处理,例如针对 Redux Saga Firebase:
// Redux Saga: Firebase Auth Channel
export function* firebaseAuthChannelSaga() {
try {
// Auth Channel (Events Emit On Login And Logout)
const authChannel = yield call(reduxSagaFirebase.auth.channel);
while (true) {
const { user } = yield take(authChannel);
// Check If User Exists
if (user) {
// Redux: Login Success
yield put(loginSuccess(user));
}
else {
// Redux: Logout Success
yield put(logoutSuccess());
}
}
}
catch (error) {
console.log(error);
}
};
答案 3 :(得分:0)
这里是如何使用 onAuthStateChanged
功能(主要是 redux-saga
)运行 eventChannel
observable
import { eventChannel } from "redux-saga";
import { take, call } from "redux-saga/effects";
const authStateChannel = function () {
return eventChannel((emit) => {
const unsubscribe = firebase.auth().onAuthStateChanged(
(doc) => emit({ doc }),
(error) => emit({ error })
);
return unsubscribe;
});
};
export const onAuthStateChanged = function* () {
const channel = yield call(authStateChannel);
while (true) {
const { doc, error } = yield take(channel);
if (error) {
// handle error
} else {
if (doc) {
// user has signed in, use `doc.toJSON()` to check
} else {
// user has signed out
}
}
}
};
请注意,其他不使用通道传奇的解决方案对于 redux-saga
不是最佳的,因为在这种情况下将可观察对象转换为承诺不是有效的解决方案,因为您每次都需要调用承诺您预计身份验证状态会发生变化(例如:执行每个 USER_SIGNED_IN
操作并调用“promisified”可观察对象),这将否定可观察对象的全部目的