Redux-saga firebase onAuthStateChanged 事件通道
Redux-saga firebase onAuthStateChanged eventChannel
如何在 redux saga 中处理 firebase auth state observer?
firebase.auth().onAuthStateChanged((user) => {
});
我想在我的应用程序启动时 运行 APP_START
传奇,这将 运行 firebase.auth().onAuthStateChanged
观察者和 运行 其他传奇取决于回调。
据我所知,eventChannel 是正确的做法。但我不明白如何让它与 firebase.auth().onAuthStateChanged
一起工作。
有人可以展示如何将 firebase.auth().onAuthStateChanged
放入 eventChannel 吗?
创建您自己的函数 onAuthStateChanged()
,它将 return 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);
您可以使用 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()
关闭频道。
这可以在 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);
}
};
这里是如何使用 redux-saga
特征(主要是 eventChannel
)
运行 onAuthStateChanged
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
}
}
}
};
请注意,其他不使用 channel sagas 的解决方案对于 redux-saga
而言并不是最佳解决方案,因为在这种情况下将可观察对象转化为 promise 不是有效的解决方案,因为您需要调用 promise每次您预期身份验证状态发生变化时(例如:采取每个 USER_SIGNED_IN
操作并调用“promisified”可观察对象),这将否定可观察对象的全部目的
如何在 redux saga 中处理 firebase auth state observer?
firebase.auth().onAuthStateChanged((user) => {
});
我想在我的应用程序启动时 运行 APP_START
传奇,这将 运行 firebase.auth().onAuthStateChanged
观察者和 运行 其他传奇取决于回调。
据我所知,eventChannel 是正确的做法。但我不明白如何让它与 firebase.auth().onAuthStateChanged
一起工作。
有人可以展示如何将 firebase.auth().onAuthStateChanged
放入 eventChannel 吗?
创建您自己的函数 onAuthStateChanged()
,它将 return 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);
您可以使用 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()
关闭频道。
这可以在 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);
}
};
这里是如何使用 redux-saga
特征(主要是 eventChannel
)
onAuthStateChanged
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
}
}
}
};
请注意,其他不使用 channel sagas 的解决方案对于 redux-saga
而言并不是最佳解决方案,因为在这种情况下将可观察对象转化为 promise 不是有效的解决方案,因为您需要调用 promise每次您预期身份验证状态发生变化时(例如:采取每个 USER_SIGNED_IN
操作并调用“promisified”可观察对象),这将否定可观察对象的全部目的