0

我正在 Ionic React 应用程序中实现 FCM 通知。我无法导航到另一个页面以显示通知详细信息。

FCMService在我的 react App 中创建了一个类,并在index.ts文件中对其进行了初始化。

// FCMService.ts

export default class FCMService {

    public static Instance: FCMService;

    private _store: Store<IAppState>;

    constructor(store: Store<IAppState>) {
        this._store = store;
    }

    public static Initalise(store: Store<IAppState>) {
        if (!FCMService.Instance) {
            FCMService.Instance = new FCMService(store);
            FCMService.Instance.InitaliseFCM();

            FCMService.Instance._store.subscribe(() => { console.log(store.getState()) });
        } else {
            console.debug("FCM service already intialised. Please use FCMService.Instance");
        }
    }

    private InitaliseFCM() {
        // Request permission to use push notifications
        // iOS will prompt user and return if they granted permission or not
        // Android will just grant without prompting
        PushNotifications.requestPermission().then(result => {
            console.log(result);
            if (result.granted) {
                // Register with Apple / Google to receive push via APNS/FCM
                PushNotifications.register();
            } else {
                // Show some error
            }
        });

        // On success, we should be able to receive notifications
        PushNotifications.addListener('registration', (token: PushNotificationToken) => {
            console.log(token);
            localStorage.setItem("FCM_TOKEN", token.value);
        }
        );

        // Some issue with our setup and push will not work
        PushNotifications.addListener('registrationError',
            (error: any) => {
                console.log(error);
            }
        );

        // Show us the notification payload if the app is open on our device
        PushNotifications.addListener('pushNotificationReceived',
            (notification: PushNotification) => {
                console.log(notification);
                let data = notification.notification.data as INotificationData;
            }
        );

        // Method called when tapping on a notification
        PushNotifications.addListener('pushNotificationActionPerformed',
            (notification: PushNotificationActionPerformed) => {
                console.log(notification);
                let data = notification.notification.data as INotificationData;

                this._store.dispatch(setNotificationActionCreator(data));
            }
        );
    }
}

然后是 index.ts

const store = configureStore();

interface MainProps {
    store: Store<IAppState>;
}

FCMService.Initalise(store);
ReactDOM.render(<Provider store={store}><App /> </Provider>, document.getElementById('root'));
serviceWorker.unregister();

我什至尝试使用 Redux 商店将通知保存在 Tap - 然后发布通知更改事件(这可能有效 - 如果我可以访问文件useHistory()中的挂钩App.tsx

这是我通过 Redux 商店导航的尝试App.tsx

const App: React.FC<IProps> = ({ getCompanies, getUser, notification }) => {
  console.log('app');
  console.log(process.env);

    const history = useHistory();
    if(notification){
        history.push(`/page/plot-position/{notification.id}`);
    }

  return (
    <IonApp>
      <IonReactRouter>
        <IonSplitPane contentId="main" when="false">

          <Menu />

          <IonRouterOutlet id="main">
            <Route path="/login" component={LoginPage} exact />
            <PrivateRoute path="/page/plot-position/:notificationId/" component={PlotPositionPage} exact />
            <Redirect from="/" to="/login" exact />
          </IonRouterOutlet>

        </IonSplitPane>
      </IonReactRouter>
    </IonApp>
  );
};

const mapStateToProps = (store: IAppState) => {
  return {
    user: store.user.user as UserDTO,
    notification: store.notificationState.notification
  };
};

const mapDispatchToProps = (dispatch: any) => {
  return {
    getCompanies: () => dispatch(getCompaniesStartActionCreator()),
    getUser: () => dispatch(getUserStartActionCreator())
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(App);
4

2 回答 2

1

看起来您的导航工作正常,但是您在将通知对象传递到页面时遇到问题?您可以通过历史状态传递对象。

要访问 useHistory 挂钩,您需要将 FCMService 设为自定义挂钩。

const useFCMService = (): void => {
  const history = useHistory();
  React.useEffect(() => {
    // Method called when tapping on a notification
    PushNotifications.addListener('pushNotificationActionPerformed', 
      (action: PushNotificationActionPerformed) => {
        const notification = action.notification.data as INotificationData;
        history.push({ pathname: '/page/plot-position/', state: { notification } });
      }
    );
  }, []);
}

然后在您的 App 组件中包含您的 useFCMService 自定义挂钩。

const App: React.FC<IProps> = ({ getCompanies, getUser }) => {
  useFCMService();
  ...
};
于 2021-02-23T15:26:36.087 回答
1

深度链接为我们提供了一种方法:使用打开应用程序的操作和打开应用程序的操作,我们可以将用户引导到正确的目的地。

打开应用程序

在这里,我们将创建一个操作来在用户点击推送通知时打开 url;少用一个监听器:

const {PushNotifications, App} = Plugins

***

PushNotifications.addListener(
        "pushNotificationActionPerformed",
        (notification: PushNotificationActionPerformed) =>{
            const data = notification.notification.data;
            if (data.packageNumber) App.openUrl({url: `com.company.appname://tabs/package-details/${data.packageNumber}`})
            else App.openUrl({url:'/tabs'})
        }
    )

com.company.app://至关重要,因为应用程序必须到达应用程序必须到达现有的给定url,否则将不会触发以下操作(捕获 url),因为它会等待App.openUrl函数的完整 true;当我们打开一个内部 url 时,它必须以电容器配置页面中给定的应用程序名称开头(参见下面的示例,我们可以在其中了解如何使用本地 url)。

通过这种方式,我们添加了一个在特定路径中打开应用程序的功能。

重定向用户

在这里,我们将完成深度链接教程中的应用程序部分:我们创建一个新的侦听器组件来处理appOpenUrl事件并重定向到用户,我们将把它放在相应的IonRouter内的主App文件中:

const AppUrlListener: React.FC<any> = () => {
  let history = useHistory();
  useEffect(() => {
    App.addListener('appUrlOpen', (data: any) => {
      const slug = data.url.split(':/').pop();
      if (slug) {
        history.push(slug);
      }
    });
  }, []);

  return null;
};

不要忘记 router 中的路由必须以 开头/,并且由于应用程序 url 包含:/,我们在这里拆分 url 得到第二部分,即 slug;我们将其推送到历史记录中,触发路由器并在您进入新路由时获得正常行为。

我们将在路由器内部添加这个组件:

<IonReactRouter>
        <IonSplitPane contentId="main">
          <Menu />
          <AppUrlListener />
          <IonRouterOutlet id="main">

现在,应用程序将监听该appOpenUrl事件,当它收到新的事件时,它将把获取的 url 推送到历史记录,将用户重定向到该路由。

于 2020-11-19T15:34:25.803 回答