在 React Native 中将推送通知组件放在哪里

Where to put push notification component in React Native

我正在使用 React Native 制作简单的新闻通知应用程序。当某些条件消息出现时,它只是向用户发送推送通知。

我先做了UI,还有基本功能。所以有一些组件可以登录、注册和添加条件组件等,而且效果很好。

最后我想将 Push Notification 应用到我的应用程序,所以我使用 Firebase Cloud Messaging(FCM)。幸运的是它运作良好。当我用一些数据(密钥 header、令牌等)请求 post 时,应用程序成功接收推送通知。

但问题是,当我测试 Push Notification 到我的应用程序时,我只是遵循示例源代码。所以我不知道如何将它应用到我现有的应用程序中。

该应用看起来像,

export default class App extends Component {
    render() {

        return (

            <Provider store={configureStore()}>
                <MenuContext>
                    <Router>
                        <Scene key="root">
                            <Scene key="login" hideNavBar component={LoginComponent} initial/>
                            <Scene key="register" hideNavBar component={RegisterComponent}/>
                            <Scene key="resetPassword" hideNavBar component={ResetPasswordComponent}/>
                            <Scene key="main" tabs
                                   tabBarStyle={{ top: 72, height: 76, backgroundColor: API.SECOND_COLOR, borderColor: API.BORDER_COLOR, borderBottomWidth: 1}}
                                   tabBarSelectedItemStyle={{ marginBottom: -1, height: 76, borderBottomWidth: 4, borderBottomColor: API.FIRST_COLOR }}
                            >
                                <Scene key="newsConditionsList" title="First Tab" iconName="alarm" icon={TabIcon}>
                                    <Scene key="scarlet" component={TabComponent1} hideNavBar initial/>
                                </Scene>
                                <Scene key="news" title="Second Tab" iconName="chat" icon={TabIcon}>
                                    <Scene key="scarlet2" component={TabComponent2} hideNavBar initial/>
                                </Scene>
                                <Scene key="settings" title="Third Tab" iconName="settings" icon={TabIcon}>
                                    <Scene key="scarlet3" component={TabComponent3} hideNavBar initial/>
                                </Scene>
                            </Scene>
                            <Scene key="addCondition" title="Add Todo" component={AddConditionComponent} hideNavBar/>
                            <Scene key="room" title="In Room" component={RoomComponent} hideNavBar/>

                        </Scene>
                    </Router>
                </MenuContext>
            </Provider>
        );
    }
}

此时,我的PushController.js该放在哪里?我认为无论 app 是否为 运行,PushController 都应该在后台执行。

PushController.js代码如下。

我不知道把这个组件放在哪里。放在哪里?请帮助我!

import React, { Component } from "react";

import FCM, {FCMEvent, RemoteNotificationResult, WillPresentNotificationResult, NotificationType} from "react-native-fcm";

import firebaseClient from  "./FirebaseClient";

export default class PushController extends Component {
    constructor(props) {
        super(props);
    }

    componentDidMount() {
        FCM.requestPermissions();

        FCM.getFCMToken().then(token => {
            console.log("TOKEN (getFCMToken)", token);
            this.props.onChangeToken(token);
        });

        FCM.getInitialNotification().then(notif => {
            console.log("INITIAL NOTIFICATION", notif)
        });

        this.notificationListner = FCM.on(FCMEvent.Notification, notif => {
            console.log("Notification", notif);
            if(notif.local_notification){
                return;
            }
            if(notif.opened_from_tray){
                return;
            }

            if(Platform.OS ==='ios'){
                //optional
                //iOS requires developers to call completionHandler to end notification process. If you do not call it your background remote notifications could be throttled, to read more about it see the above documentation link.
                //This library handles it for you automatically with default behavior (for remote notification, finish with NoData; for WillPresent, finish depend on "show_in_foreground"). However if you want to return different result, follow the following code to override
                //notif._notificationType is available for iOS platfrom
                switch(notif._notificationType){
                    case NotificationType.Remote:
                        notif.finish(RemoteNotificationResult.NewData) //other types available: RemoteNotificationResult.NewData, RemoteNotificationResult.ResultFailed
                        break;
                    case NotificationType.NotificationResponse:
                        notif.finish();
                        break;
                    case NotificationType.WillPresent:
                        notif.finish(WillPresentNotificationResult.All) //other types available: WillPresentNotificationResult.None
                        break;
                }
            }
            this.showLocalNotification(notif);
        });

        this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken, token => {
            console.log("TOKEN (refreshUnsubscribe)", token);
            this.props.onChangeToken(token);
        });
    }

    showLocalNotification(notif) {
        FCM.presentLocalNotification({ 
            title: notif.title,
            body: notif.body,
            priority: "high",
            click_action: notif.click_action,
            show_in_foreground: true,
            local: true
        });
    }

    componentWillUnmount() {
        this.notificationListner.remove();
        this.refreshTokenListener.remove();
    }


    render() {
        return null;
    }
}

PushController 组件放在哪里并不重要,只要它保持安装状态即可。事实上,您根本不需要特殊组件,但您可以拥有它:)

如此简单的答案可能会放入您的 App。例如

<View>
  <PushController />
  <Provider store={configureStore()}>
    ...
  </Provider>
</View>

唯一重要的是您在应用程序启动时通过 FCM 调用正确注册您的设备。