android - 没有导航道具的 React Navigation 在发布模式下不起作用(Android 签名应用程序)
问题描述
我正在实现一个接收 firebase 推送通知的 react-native 应用程序。当通知到达时,应用导航到屏幕以显示通知。我使用参考遵循了这种方法:“没有导航道具的导航” 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
我使用的不是类组件而是功能组件。
// 导航器.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);
// 应用程序.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) }} />
);
// 导航Ref.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
})
);
};
在调试模式下,使用 `navigate('any screen') 就像一个魅力,但在发布模式下,它不起作用。
但是一件奇怪的事情是以下导航有效。当应用程序不是前台状态时,用户会打开推送通知。
// 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) 上。
为什么 navigation('Help') 在发布模式下不起作用?我搜索了很多文档,我觉得它也应该在发布模式下工作。
有没有其他方法可以从顶层导航到屏幕(如 App.js)?
解决方案
我找到了问题的根源。我测试了几件事。我想知道发布模式下非常简单的应用程序是否可以正确导航。所以,我只是关注了这个帖子: https ://medium.com/@katharinep/firebase-notification-integration-in-react-native-0-60-3a8d6c8d56ff
以下是我所做的: - 创建了两个屏幕:主页和通知。- 使用最新的 react-native@0.60.6 和 react-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
})
);
};
我只是使用了 react-navigation 中的代码: 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,
}
然后我工作了!我不知道这两个代码的区别。第一个在调试模式下完美运行,但在发布模式下却不行,尤其是应用程序在前台。
谁能告诉我区别?为什么第一个代码不起作用?
推荐阅读
- javascript - 获取另一个域上页面的内容
- vba - 在 word 中导入宏 - Visual Basic 错误
- php - 如何在本地计算机上安装的服务器上编写程序包?
- java - 无法加载请求的类:Tomcat 和 IntelliJ 上的 com.mysql.jdbc.Driver
- javascript - 从单独的 JavaScript 文件禁用另一个 HTML 文件上的按钮
- javascript - 在 Angular 中使用 jQuery 是一种不好的做法吗?
- angularjs - 无法在我的控制器 AngularjS 中访问表单内容,例如用户名...
- php - 中间字符串 RegEx/PHP 空格删除“在其他地方”工作
- reactjs - 如何使用 Jest 和 Enzyme 测试按钮的 onClick 道具
- django - AttributeError:“ModelFormOptions”对象没有属性“private_fields”