我正在使用React Native Firebase,并且在需要时会收到通知,这些通知中有一些数据可导航到特定屏幕。 我使用了Firebase文档来实现该功能,但无法正常运行
这是我使用过的文档Firebase & React-Navigation 我的代码看起来像这样:
const Stack = createStackNavigator();
const Router = () => {
const navigation = useNavigation();
const [loading, setLoading] = useState(true);
const [initialRoute, setInitialRoute] = useState('Splash');
useEffect(() => {
//fcm
registerAppWithFCM();
// checkRNFBPermission();
const unsubscribe = messaging().onMessage(async remoteMessage => {
console.log('remote DATAAAAAAAAAAAAAAAAAAAAAAAA : ',remoteMessage.data);
// switch (remoteMessage.data.screen) {
// case 'answer':{
// console.log('inside switch condition 1 !!!!!!!!!!!!!');
// useNavigation().navigate('Profile');
// break;
// }
// case 'AnswerQuestion':{
// console.log('inside switch condition 2 !!!!!!!!!!!!!');
// useNavigation().navigate('Profile');
// break;
// }
// default:
// break;
// }
// Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage));
// const owner = JSON.parse(remoteMessage.data.owner);
// const user = JSON.parse(remoteMessage.data.user);
// const picture = JSON.parse(remoteMessage.data.picture);
});
// Assume a message-notification contains a "type" property in the data payload of the screen to open
messaging().onNotificationOpenedApp(remoteMessage => {
console.log(
'Notification caused app to open from background state:',
remoteMessage.notification,
);
navigation.navigate('Profile');
});
// Check whether an initial notification is available
messaging()
.getInitialNotification()
.then(remoteMessage => {
if (remoteMessage) {
console.log(
'Notification caused app to open from quit state:',
remoteMessage.data, //notification
);
}
setLoading(false);
});
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
});
return unsubscribe;
//fcm
}, []);
//fcm
checkRNFBPermission = async() => {
const enabled = await messaging().hasPermission();
if(enabled){
messaging()
.getToken()
.then(token => {
// console.log('deviceeeee fcm token ------> ', token);
});
}else{
requestUserPermission();
}
}
registerAppWithFCM = async() => {
await messaging().registerDeviceForRemoteMessages();
}
requestUserPermission = async() => {
const settings = await messaging().requestPermission();
if (settings) {
console.log('Permission settings:', settings);
}
}
//fcm
renderLoading = () => (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Domanda</Text>
<ActivityIndicator size='large' color={colors.darkerTeal} />
</View>
);
//firebase
if (loading) {
return null;
}
//firebase
return(
<Provider store={store}>
<PersistGate persistor={persistor} loading={this.renderLoading()}>
<Root>
<NavigationContainer>
<Stack.Navigator initialRouteName={initialRoute} headerMode="none">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Login" component={Login} />
<Stack.Screen name="Main" component={Main} />
<Stack.Screen name="AppIntro" component={AppIntro} />
<Stack.Screen name="Tags" component={Tags} />
<Stack.Screen name="Answers" component={Answers} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="EditInfo" component={EditInfo} />
<Stack.Screen name="ChangePassword" component={ChangePassword} />
<Stack.Screen name="AnswerQuestion" component={AnswerQuestion} />
<Stack.Screen name="ContactUs" component={ContactUs} />
</Stack.Navigator>
</NavigationContainer>
</Root>
</PersistGate>
</Provider>
)
};
export default Router;
但是当我添加usenavigation并想要使用它时,它将引发此错误: 错误:我们找不到导航对象。您的组件是否在导航器的屏幕内?
我无法使用navigation.navigate('Profile');
导航到特定屏幕。
答案 0 :(得分:1)
您正在App.js中收到消息,StackNavigator之外的消息。 您可以使用ref来使用导航器的导航属性
在您的app.js顶部定义导航器
var navigator = null;
然后将引用添加到导航器
<Stack.Navigator
initialRouteName={initialRoute}
headerMode="none"
ref={nav => {
navigator = nav;
}}
>
并将您的路线推入接收方法
navigator.dispatch(
NavigationActions.navigate({
routeName: 'theRoute',
params: {},
}),
);
答案 1 :(得分:0)
挣扎了4个小时...
某些组件在其中,可以进行导航(在我的情况下为“主屏幕”)
//上次导入
import { ScrollWrapper } from './styles'
export const navigationRef = React.createRef();
export const isReadyRef = React.createRef();
export function navigate(name, params) {
if (isReadyRef.current && navigationRef.current) {
// Perform navigation if the app has mounted
navigationRef.current.navigate(name, params);
} else {
console.log(' else [ELSE] --- ')
// You can decide what to do if the app hasn't mounted
// You can ignore this, or add these actions to a queue you can call later
}
}
// component start
export const SocialHomeScreen = () => {...
在App.js中
从'./screens/PeopleAroundYou/index'导入{导航,navigationRef,isReadyRef}
// ....导航器
const App = () => {
const [isAuth, setIsAuth] = useState(false)
AsyncStorage.getItem('pushNotify').then(value => {
console.log('value --- ', value)
console.log('JSON.parse(value) --- ', JSON.parse(value))
}).catch(error => {
console.log('error --- ', error)
})
// foreground message arrived
useEffect(() => {
return messaging().onMessage(async remoteMessage => {
const { data, notification } = remoteMessage
if (data.type === 'activity-check-in') {
console.log(' A new FCM message arrived! --- ')
console.log('data --- ', data)
console.log('notification --- ', notification)
console.log(' navigator --- ', navigate)
console.log('navigationRef.current.getRootState() --- ', navigationRef.current.getRootState())
switch (data.category) {
case 'fitness':
// navigate to nested screen
navigate(routes.Fitness, {
screen: routes.ActivityDetails,
params: { activityId: data.eventId}
})
break
case 'companionship':
navigate(routes.Companionships, {
screen: routes.ActivityDetails,
params: { activityId: data.eventId}
})
break
case 'volunteering':
navigate(routes.Volunteering, {
screen: routes.ActivityDetails,
params: { activityId: data.eventId}
})
break
case 'wellbeing':
navigate(routes.Wellbeing, {
screen: routes.ActivityDetails,
params: { activityId: data.eventId}
})
break
}
}
})
}, [])
useEffect(() => {
SplashScreen.hide()
fcmService.registerAppWithFCM()
fcmService.register(onRegister, onNotification, onOpenNotification)
localNotificationService.configure(onOpenNotification)
function onRegister(token) {
console.log('[App] onRegister: ', token)
}
function onNotification(notify) {
console.log('[App] onNotification: ', notify)
const options = {
soundName: 'default',
playSound: true, //,
// largeIcon: 'ic_launcher', // add icon large for Android (Link: app/src/main/mipmap)
// smallIcon: 'ic_launcher' // add icon small for Android (Link: app/src/main/mipmap)
}
localNotificationService.showNotification(
0,
notify.title,
notify.body,
notify,
options,
)
}
function onOpenNotification(notify) {
console.log('[App] onOpenNotification: ', notify)
Alert.alert('Open Notification: ' + notify.body)
}
return () => {
console.log('[App] unRegister')
fcmService.unRegister()
localNotificationService.unregister()
}
}, [])
const authContext = useMemo(() => {
return {
login: () => {
setIsAuth(true)
},
logout: () => {
setIsAuth(false)
},
}
})
return (
<AuthContext.Provider value={authContext}>
<ThemeProvider theme={theme}>
<NavigationContainer
ref={navigationRef}
onReady={() => {
isReadyRef.current = true
}}
linking={linking}
fallback={
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Loader loading size='large' color='#61A5C8'/>
</View>
}
>
{isAuth ? <AuthorizedTabs /> : <NonAuthorizedStack/>}
</NavigationContainer>
</ThemeProvider>
</AuthContext.Provider>
)
}