从退出状态与RN Firebase消息传递/ React导航的深度链接不工作

uz75evzq  于 2023-02-20  发布在  React
关注(0)|答案(1)|浏览(105)

预期行为:用户通过Firebase-〉用户点击通知-〉应用程序打开并转到正确页面获得通知。
实际行为:当用户点击通知时(应用程序处于退出状态),应用程序正常打开
我已经得到了这个工作时,应用程序是在后台,但不是当应用程序处于退出状态(用户已刷卡离开)。我不知道为什么这是不工作。
我使用RN Firebase进行通知,使用React Navigation进行导航
首先,下面是使用的软件包

// client Package.json

"dependencies": {
    "@react-native-async-storage/async-storage": "^1.15.9",
    "@react-native-community/masked-view": "^0.1.11",
    "@react-native-firebase/analytics": "^14.3.2",
    "@react-native-firebase/app": "^14.3.2",
    "@react-native-firebase/messaging": "^14.3.2",
    "@react-navigation/bottom-tabs": "^6.3.3",
    "@react-navigation/native": "^6.0.8",
    "@react-navigation/native-stack": "^6.5.0",
    "@reduxjs/toolkit": "^1.8.5",
    "@trpc/client": "^9.16.0",
    "babel-plugin-inline-import": "^3.0.0",
    "native-base": "^3.0.7",
    "app-symlink-folder": "file:../common",
    "react": "17.0.2",
    "react-error-boundary": "^3.1.4",
    "react-native": "0.66.1",
    "react-native-async-storage": "^0.0.1",
    "react-native-autogrow-textinput": "^5.4.0",
    "react-native-confirmation-code-field": "^7.3.0",
    "react-native-date-picker": "^4.0.0",
    "react-native-drag-sort": "^2.4.4",
    "react-native-geolocation-service": "^5.3.0-beta.4",
    "react-native-gesture-handler": "^2.2.0",
    "react-native-image-crop-picker": "^0.36.2",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-keyboard-spacer": "^0.4.1",
    "react-native-keychain": "^8.1.0",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-permissions": "^3.2.0",
    "react-native-reanimated": "^2.4.1",
    "react-native-safe-area-context": "^3.4.0",
    "react-native-screens": "^3.12.0",
    "react-native-size-matters": "^0.4.0",
    "react-native-svg": "^12.1.1",
    "react-native-vector-icons": "^8.1.0",
    "react-native-webview": "^11.15.0",
    "react-redux": "^7.2.4",
    "redux": "^4.1.0",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.3.0",
    "rn-swipe-button": "^1.3.7",
    "styled-components": "^5.3.0",
    "styled-system": "^5.1.5",
    "zod": "3.19.0"
}
// backend package.json


"dependencies": {
        "@googlemaps/google-maps-services-js": "^3.3.8",
        "@trpc/client": "^9.16.0",
        "@trpc/server": "^9.16.0",
        "dotenv-safe": "^8.2.0",
        "express": "^4.17.1",
        "firebase-admin": "^11.0.1",
        "firebase-tools": "^11.8.1",
        "jsonwebtoken": "^8.5.1",
        "morgan": "^1.10.0",
        "multer": "^1.4.4",
        "node-fetch": "^2.6.1",
        "pg": "^8.6.0",
        "pg-format": "^1.0.4",
        "app-symlinked-folder": "link:../common",
        "sharp": "^0.30.6",
        "shuffle-array": "^1.0.1",
        "twilio": "^3.71.1",
        "zod": "3.19.0"
    },

下面是要发送的通知对象

// firebaseMessaging
const firebaseResults = await admin.messaging().sendToDevice(fcm, {
            data: {
                type: "MESSAGE",
                url: 'myApp://app/screen1'
            } as notification.NotificationData,
            notification: {
                title: 'title',
                body: 'body'
            },
        },{
            contentAvailable: true
        });

这是应用程序入口点

// index.js


import React, { useEffect } from 'react';
import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';
import fcm from '@react-native-firebase/messaging';
import * as notificationTypes from 'app-symlink-folder/notification'
import { Linking } from 'react-native';

fcm().setBackgroundMessageHandler(async(message) => {
    const parsedData = notificationTypes.notificationData.parse(message.data);
    if (parsedData.url) {
      // ** Note ** this openURL method isn't working. Some console logs have shown that it's being reached when the user opens the notification from the quit state
      await Linking.openURL(parsedData.url)
    }
  })

const FakeApp = () => {
  useEffect(()=> {
    console.log('inside fake app')
  },[])
  return null
}

function HeadlessCheck({isHeadless}) {
  fcm().getIsHeadless().then((fcmHeadless)=> {
    console.log('headless status', isHeadless, fcmHeadless)
    if (isHeadless || fcmHeadless) return <FakeApp />

  })
  return <App />
}

// Note: I've found some SO and git threads suggesting to do this. I don't think it's really made any difference since I've been working on IOS. I think this is for Android.
AppRegistry.registerComponent(appName, () => HeadlessCheck);

tsx大多只是容器和提供者

// App.tsx
export default function App() {
   return (
      <Providers and containers>
         <RootNavigation />
      </ ...>
   )
}

这是根导航器,它负责引导所有内容

const RootNavigator = () => {

const config:LinkingOptions<RootStackParamList>['config'] = {
    screens: {
      CHAT: {
        path: `chat/:otherUserId/:channelId/`,
        parse: {
          otherUserId: (otherUserId:string) => `${otherUserId}`,
          channelId: (channelId:string) => `${channelId}`,
        }
      },
      APP: {
        path: 'app/',
        screens: {
          'SCREEN1': "screen1/",
          'SCREEN2': "screen2/"
        }
      },
      HOMEPAGE: HOMEPAGE,
      NOTFOUND: '*'
    }
  }
  // linking used for React Navigation deep linking
  const linking:LinkingOptions<RootStackParamList> = {
    // url scheme
    prefixes: ['myApp://'],
    config
  }


  useEffect(()=> {
    const unsubscribe = fcm().onNotificationOpenedApp((message) => {
      const parsedData = notificationTypes.notificationData.parse(message.data);
      if (parsedData.url) {
        Linking.openURL(parsedData.url)
      }
    })
    return unsubscribe
  },[])

  // app navigator
  const AppNavigator = () => {
     

useEffect(() => {

    // cleanup function for fcm
    const unsubscribeFCM = fcm().onMessage(async remoteMessage => {

      const parsedData = notificationTypes.notificationData.parse(
        remoteMessage.data,
      );
      // do stuff with parsedData
      return unsubscribeFCM
    });

    
    // set up permissions for fcm
    (async () => {
      fcm()
        .hasPermission()
        .then(status => {
          if (status !== fcm.AuthorizationStatus.AUTHORIZED) {
            fcm()
              .requestPermission()
              .catch(e => {
                // handle error
              });
          }
        });
    })();
    return unsubscribeFCM;
  }, []);

  return (
    

         <Tab.Navigator>
            <Stack.Screen name={SCREEN1} component={Screen1} />
            <Stack.Screen name={SCREEN2} component={Screen2} />
         </Tab.Navigator>
       )

  }

  return (
      <NavigationContainer 
         linking={linking}
         fallback={<FallBack />}
         ref={navigationRef} 
         onReady={persistantLoginThunk()}
      />
         <Stack.Navigator>
            <Stack.Screen name={HOMEPAGE} component={HomePage} />
            <Stack.Screen name={CHAT} component={Chat} />
            <Stack.Screen name={APP} component={AppNavigator} />
         </Stack.Navigator>
  )


}
gwbalxhn

gwbalxhn1#

您应该用途:
获取初始通知:从退出状态打开应用程序时。
关于通知打开的应用程序:当应用程序运行时,但在后台。
而不是 * 设置背景消息处理程序 *
请参见https://rnfirebase.io/messaging/notifications#handling-interaction

相关问题