Redux传奇Firebase onAuthStateChanged eventChannel

时间:2018-08-03 12:31:22

标签: firebase firebase-authentication redux-saga

如何在Redux传奇中处理Firebase身份状态观察器?

firebase.auth().onAuthStateChanged((user) => {

});

我想在我的应用启动时运行APP_START传奇,它将运行firebase.auth().onAuthStateChanged观察者,并根据回调运行其他sagas。

据我了解, eventChannel 是正确的方法。但是我不知道如何使其与firebase.auth().onAuthStateChanged一起使用。

有人可以显示如何将firebase.auth().onAuthStateChanged放入eventChannel吗?

4 个答案:

答案 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”可观察对象),这将否定可观察对象的全部目的