React Navigation без навигационной поддержки не работает в режиме релиза (приложение с подписью Android) - PullRequest
1 голос
/ 23 сентября 2019

Я внедряю приложение-ответ, получающее push-уведомления от firebase.Когда уведомление приходит, приложение переходит на экран, чтобы показать уведомление.Я следовал этому подходу, используя ссылку: «Навигация без навигационной стойки» https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html

Когда я тестировал это в режиме отладки, он работает отлично.Но когда я тестировал в режиме релиза (приложение с подписью Android), оно не работает.

Особенно, когда уведомление приходит, когда приложение открыто, оно не работает.Нет сообщения об ошибке, и приложение зависает, и примерно через 30 секунд приложение вылетает.

Вот информация о пакете:

    "react": "16.8.3",
    "react-i18next": "10.12.2",
    "react-native": "0.59.10",
    "react-native-firebase": "5.5.6",
    "react-native-gesture-handler": "1.3.0",
    "react-navigation": "3.11.1",

По сути, я пробовал это "Навигация безнавигационная опора "https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html

Аналогично, этот тоже: https://github.com/react-navigation/react-navigation/issues/742

Я использую не компонент класса, а функциональный компонент.

// Navigator.js

const switchNavigator = createSwitchNavigator({
  ResolveAuth: ResolveAuthScreen,
  loginFlow: createStackNavigator({
    Signin: SigninScreen,
    Signup: SignupScreen
  }),
  helpFlow: createStackNavigator({
    Help: HelpScreen,
  }, {headerLayoutPreset: 'center'}),
  mainFlow: createBottomTabNavigator({
    Ask: createStackNavigator({
      AskMain: AskScreen,
      AskWait: AskWaitScreen,
    }, {headerLayoutPreset: 'center'}),
    Chat: createStackNavigator({
      ChatList: ChatListScreen,
      Chatting: ChatScreen,
    }, {headerLayoutPreset: 'center'}),
    Profile: createStackNavigator({
      Account: AccountScreen,
      AccountEdit: AccountEditScreen,
      ProfileContract: ProfileScreen
    }
    , {headerLayoutPreset: 'center'})
  },
...
export default createAppContainer(switchNavigator);

// App.js

import Navigator from './Navigator';
import { useTranslation } from 'react-i18next';
import { navigate, setNavigator } from './src/navigationRef';

const App = Navigator;

export default () => {

  // setup language
  const { t } = useTranslation();

  // use effect
  useEffect(() => {

    // notification listener (triggered when a particular notification has been received)
    // if the app is foreground, we need to navigate the screen
    const listenerFG = firebase.notifications().onNotification((notification: Notification) => {
      console.log('onNotification', notification);
      Alert.alert(
        t('AppScreen.title'),
        t('AppScreen.message'),
        [
          {text: t('yes'), onPress: () => navigate('Help', { notificationBody: notification })},
        ],
        {cancelable: true},
      );
    });

   listenerForAppClosed();

   return () => {
      listenerFG();
    }
  }, []);

  return (
    <App ref={(navigator) => { setNavigator(navigator) }} /> 
  );

// navigationRef.js

import { NavigationActions } from 'react-navigation';

let navigator;

// nav is coming from react navigation
export const setNavigator = navRef => {
  console.log('navigation ref', navRef);
  // set navigator
  navigator = navRef;
};

export const navigate = (routeName, params) => {
  console.log('[navigate dispatch] navigator', navigator);
  navigator.dispatch(
    NavigationActions.navigate({
      routeName,
      params
    })
  );
};

В режиме отладки работает `навигация ('любой экран'))как брелок, но в режиме релиза он не работает.

Но одна странная вещь в том, что работает следующая навигация.Пользователь открывает push-уведомление, когда приложение не находится на переднем плане.

// часть файла App.js

// listen the notification being opened or clicked when the app is closed
  const listenerForAppClosed = async() => {
    // app closed
    const notificationOpen: NotificationOpen = await firebase.notifications().getInitialNotification();
    if (notificationOpen) {
      // app was opened by a notification
      console.log('getInitialNotification', notificationOpen);
      // get information about the notification that was opened
      const notification: Notification = notificationOpen.notification;
      //// ignore the same notification id since the same notification is received again, don't know why.
      // get noti id from storage
      const notiId = await AsyncStorage.getItem('notiId');
      // set noti id to storage
      await AsyncStorage.setItem('notiId', notification.notificationId);     
      if (notification.notificationId === notiId) {
        console.log('notification id is the same');       
      } else { 
        console.log('navigating to helpscreen...');   
        // navigate to Help screen
        navigate('Help', { notificationBody: notification });
      }
    }
  }

Проблема возникает как на эмуляторе Android, так и на устройстве (Android9).

Зачем нужна навигация («Справка»)не работает в режиме релиза?Я искал много документов и чувствую, что он должен работать и в режиме релиза.

Есть ли другой способ перехода на экран с верхнего уровня (например, App.js)?

1 Ответ

0 голосов
/ 25 сентября 2019

Я нашел источник проблемы.Я проверил несколько вещей.Я хотел знать, правильно ли перемещается очень простое приложение в режиме релиза.Итак, я просто следовал за этой публикацией: https://medium.com/@katharinep/firebase-notification-integration-in-react-native-0-60-3a8d6c8d56ff

Вот что я сделал: - создал два экрана: Дом и Уведомление.- Воссоздала приложение с последними реагирующими@0.60.6 и response-navigation@4.0.9 - отправляла облачное сообщение не из приложения, а из облачной службы Firebase

Это сработало!Когда приходит уведомление, приложение переходит на экран уведомлений.

Поэтому я попытался отследить источник проблемы.- попытался добавить больше экранов - добавил больше провайдеров и контекст - отправил сообщение из приложения

Наконец, я нашел источник.Именно так я и использовал 'navigateRef.js'. Первоначально я использовал его так:

// App.js
import { navigate, setNavigator } from './src/navigationRef';
<App ref={(navigator) => { setNavigator(navigator) }} /> 
// navigationRef.js
import { NavigationActions } from 'react-navigation';

let navigator;

// nav is coming from react navigation
export const setNavigator = navRef => {
  console.log('navigation ref', navRef);
  // set navigator
  navigator = navRef;
};

export const navigate = (routeName, params) => {
  console.log('[navigate dispatch] navigator', navigator);
  navigator.dispatch(
    NavigationActions.navigate({
      routeName,
      params
    })
  );
};

Я просто использовал точный код от реагирования-навигации: https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html

// App.js
import NavigationService from './src/NavigationService';
<App
    ref={navigationRef => 
      {NavigationService.setTopLevelNavigator(navigationRef);}}
/>
// NavigationService.js
import { NavigationActions } from 'react-navigation';

let _navigator;

function setTopLevelNavigator(navigatorRef) {
  _navigator = navigatorRef;
}

function navigate(routeName, params) {
  _navigator.dispatch(
    NavigationActions.navigate({
      routeName,
      params,
    })
  );
}

// add other navigation functions that you need and export them

export default {
  navigate,
  setTopLevelNavigator,
}

Тогда я работал!Я не знаю разницы этих двух кодов.Первый отлично работал в режиме отладки, но не в режиме выпуска, особенно приложение на переднем плане.

Может кто-нибудь сказать мне разницу?Почему первый код не работает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...