Как я могу заставить мой firebase-слушатель загружать данные в мое избыточное состояние в приложении React Native, чтобы я мог читать данные в своей функции ComponentDidMount? - PullRequest
0 голосов
/ 25 июня 2018

Я пытаюсь загрузить токен уведомления (notificationToken), который я сохранил в Firebase, в компонент React Native.

Как только notificationToken загружен в мое состояние приращения, я хочу проверить наличие разрешений для моего устройства, чтобы увидеть, истек ли срок действия notificationToken в функции getExistingPermission(), которую я запускаю в componentDidMount().

Если срок действия токена истек, то я заменю токен в Firebase новым токеном. Если это то же самое, то ничего не происходит (что подразумевается функциональность).

Когда я запускаю свою функцию getExistingPermission(), чтобы проверить, актуален ли токен, прослушиватель Firebase, который извлекает notificationToken, не загружается вовремя, и поэтому он всегда выполняет запись в базу данных Firebase. с «новым» токеном.

Я почти уверен, что использование async / await решит эту проблему, но не смог заставить его работать. Есть идеи, как я могу убедиться, что notificationToken загружается из базы данных в мое редукционное состояние в первую очередь, прежде чем я запускаю какие-либо функции внутри моей функции componentDidMount()? Код ниже - спасибо!

ЦСИ / экраны / Dashboard.js

Должен ли я использовать оператор .then() или async / await для обеспечения загрузки уведомлений до запуска его через функцию getExistingPermission()?

import {
  getExistingPermission
} from '../components/Notifications/NotificationFunctions';

componentDidMount = async () => {
        // Listener that loads the user, reminders, contacts, and notification data
        this.unsubscribeCurrentUserListener = currentUserListener((snapshot) => {
          try {
            this.props.watchUserData();
          } catch (e) {
            this.setState({ error: e, });
          }
        });
        if (
          !getExistingPermission(
            this.props.notificationToken, //this doesn't load in time
            this.props.user.uid)
          ) {
          this.setState({ showNotificationsModal: true });
        }
      };

SRC / компоненты / Уведомления / NotificationFunctions.js

Проблема, вероятно, не здесь

export const getExistingPermission = async (
  notificationToken,
  uid,
) => {
  const { status: existingStatus } = await Permissions.askAsync(
    Permissions.NOTIFICATIONS
  );
  if (existingStatus !== 'granted') {
    console.log('status not granted');
    return false;
  } else {
    let token = await Notifications.getExpoPushTokenAsync();
    /* compare to the firebase token; if it's the same, do nothing,
    if it's different, replace */
    if (token === notificationToken) {
      console.log('existing token loaded');
      return true;
    } else {
      console.log('token: ' + token);
      console.log('notificationToken: ' + notificationToken);
      console.log('token is not loading, re-writing token to firebase');
      writeNotificationToken(uid, token);
      return false;
    }
  }
};

SRC / действия / actions.js

// Permissions stuff
watchPermissions = (uid) => (
  (dispatch) => {
    getPermissions(uid + '/notificationToken', (snapshot) => {
      try {
        dispatch(loadNotificationToken(Object.values([snapshot.val()])[0]));
      }
      catch (error) {
        dispatch(loadNotificationToken(''));

        // I could call a modal here so this can be raised at any point of the flow
      }
    });
  }
);

// User Stuff
export const watchUserData = () => (
  (dispatch) => {
    currentUserListener((user) => {
      if (user !== null) {
        console.log('from action creator: ' + user.displayName);
        dispatch(loadUser(user));
        dispatch(watchReminderData(user.uid));  //listener to pull reminder data
        dispatch(watchContactData(user.uid));  //listener to pull contact data
        dispatch(watchPermissions(user.uid));  //listener to pull notificationToken
      } else {
        console.log('from action creator: ' + user);
        dispatch(removeUser(user));
        dispatch(logOutUser(false));
        dispatch(NavigationActions.navigate({ routeName: 'Login' }));
      }
    });
  }
);

export const loadNotificationToken = (notificationToken) => (
  {
    type: 'LOAD_NOTIFICATION_TOKEN',
    notificationToken,
  }
);

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Посмотрите на избыточных подписчиков для этого: https://redux.js.org/api-reference/store#subscribe.Я внедряю подписчика для управления небольшим конечным автоматом, таким как STATE1_DO_THIS, STATE2_THEN_DO_THAT, и сохраняю это состояние в избыточном коде и использую его для визуализации вашего компонента.Только подписчик должен изменить эти состояния.Это дает вам хороший способ обрабатывать сложные потоки, когда вы хотите дождаться окончания действия1 перед выполнением действия2.Это помогает?

0 голосов
/ 25 июня 2018

Тони дал мне ответ. Необходимо переместить проверку разрешений на componentDidUpdate(). Для тех, у кого похожая проблема, компонент выглядит так:

ЦСИ / экраны / Dashboard.js

componentDidUpdate = (prevProps) => {
    if (!prevProps.notificationToken && this.props.notificationToken) {
      if (!getExistingPermission(
        this.props.notificationToken,
        this.props.user.uid
      )) {
        this.setState({ showNotificationsModal: true });
      }
    }
  };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...