簡體   English   中英

按下 rnfirebase 通知后如何導航到特定屏幕

[英]how to navigate to specific screen after pressing rnfirebase notification

我正在使用 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 並且我想使用它時,它會引發此錯誤:錯誤:我們找不到導航 object。 您的組件是否在導航器的屏幕內?

在此處輸入圖像描述

我不能使用navigation.navigate('Profile'); 導航到特定屏幕。

您在 StackNavigator 之外的 App.js 中收到消息。 您可以使用 ref 來使用導航器的導航屬性

在 app.js 頂部定義導航器

var navigator = null;

然后將 ref 添加到導航器

<Stack.Navigator 
  initialRouteName={initialRoute}
  headerMode="none"
   ref={nav => {
     navigator = nav;
   }}
 >

並在接收方法中推送您的路線

navigator.dispatch(
  NavigationActions.navigate({
     routeName: 'theRoute',
       params: {},
   }),
 );

掙扎了4個小時...

  1. 有些在組件中,導航是否可用(在我的情況下是“主屏幕”)

    // 最后一次導入

     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 = () => {...
  2. 在 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>
  )
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM