美文网首页
React native - Push Notification

React native - Push Notification

作者: Levi段玉磊 | 来源:发表于2020-12-03 14:34 被阅读0次

    How to add Push Notification in your project? I use firebase to send cloud messages by Push Notification. First of all, you click the website "https://rnfirebase.io/" , and click the menu "Cloud Messaging"

    Installation

    # Install & set up the app module
    yarn add @react-native-firebase/app
    
    # Install the messaging module
    yarn add @react-native-firebase/messaging
    
    # If you're developing your app using iOS, run this command
    cd ios/ && pod install
    

    iOS Setup

    AppDelegate.m

    @import Firebase;
    
    @interface AppDelegate () <FIRMessagingDelegate>
    
    @end
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [FIRApp configure];
        [application registerForRemoteNotifications];
        [FIRMessaging messaging].delegate = self;
    }
    
    - (void) messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
        NSLog(@"FCM registration token: %@", fcmToken);
        // Notify about received token.
        NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
        [[NSNotificationCenter defaultCenter] postNotificationName:
         @"FCMToken" object:nil userInfo:dataDict];
        // TODO: If necessary send token to application server.
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }
    
    
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
      NSLog(@"error: %@", error);
    }
    
    

    Android Setup

    /appName/android/app/src/main/AndroidManifest.xml

    <service android:name=".MyFirebaseMessagingService" android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

    /android/app/src/main/java/com/appName/MyFirebaseMessagingService.java

    package com.stylepedia;
    
    import com.google.firebase.messaging.FirebaseMessagingService;
    import com.google.firebase.messaging.RemoteMessage;
    import android.util.Log;
    
    public class MyFirebaseMessagingService extends FirebaseMessagingService {
        private final String TAG = "FCMDemo";
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
    
            // TODO(developer): Handle FCM messages here.
            Log.d(TAG, "From: " + remoteMessage.getFrom());
    
            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            }
    
            // Check if the message contains a notification payload.
            if (remoteMessage.getNotification() != null) {
                Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            }
    
            // Also if you intend on generating your own notifications as a result of a received FCM
            // message, here is where that should be initiated. See sendNotification method below.
        }
    
        private void sendRegistrationToServer(String token) {
            // TODO: Implement this method to send token to your app server.
        }
    
        @Override
        public void onNewToken(String token) {
            Log.d(TAG, "From: " + token);
            sendRegistrationToServer(token);
        }
    }
    

    React Native

    You can get token by this function, if the device didn't open Push Notification, you won't get the token, so you make sure that the user have opened the notifications.

    import messaging from '@react-native-firebase/messaging'
    
    if (!messaging().isDeviceRegisteredForRemoteMessages) {
        messaging().registerDeviceForRemoteMessages()
    }
    messaging().getToken()
    .then(fcmToken => {
      if (fcmToken) {
        console.warn(fcmToken)
        if (Platform.OS === 'ios') {
          this.iosTokenNetWork(fcmToken)
        }
        else {
          this.androidTokenNetWork(fcmToken)
        }
      } else {
        console.warn('user doesn t have a device token yet')
        // user doesn't have a device token yet
      }
    })
    

    You can use this function to check if the user opens the push notification switch on the user's device.

    messaging().requestPermission().then((response: any) => {
      //
    }
    
    // if user click allow app push notification on pop-up,I can get token by function: 
    
    messaging().requestPermission().then((response: any) => {
        if (!messaging().isDeviceRegisteredForRemoteMessages) {
            messaging().registerDeviceForRemoteMessages()
          }
          messaging().getToken()
            .then(fcmToken => {
              if (fcmToken) {
                if (Platform.OS === 'ios') {
                  this.iosTokenNetWork(fcmToken)
                }
                else {
                  this.androidTokenNetWork(fcmToken)
                }
              } else {
                console.warn('user doesn t have a device token yet')
                // user doesn't have a device token yet
              }
            })
    })
    
    

    You can click Push notification and go to another page when the App is in the background.

    messaging().setBackgroundMessageHandler(async remoteMessage => {
            if (remoteMessage) {
              appsFlyer.trackEvent("Open_notification")
              analytics().logEvent('Open_notification', {
                value: '',
              });
              if (remoteMessage.data.send_user_history_id) {
                this.pushRequest(remoteMessage.data.send_user_history_id)
              }
              if (remoteMessage.data.url === "MixMatch") {  
                  this.props.navigation.push('MyClosetDetailPage', {
                    product_id: remoteMessage.data.push_id,
                    returnPage: 'Tabs',
                  })
      
              }
              if (remoteMessage.data.url === "StreetSnap") {
                this.timer = setTimeout(() => {
                  this.props.navigation.navigate('PushlookbookStreetSnapPage', {
                    streetId: remoteMessage.data.push_id,
                    returnPage: 'Tabs',
                  })
                }, 500);
              }
          }
    });
    

    You can click Push notification and go to another page when the App is closed

    messaging()
          .getInitialNotification()
          .then(remoteMessage => {
            if (remoteMessage) {
              appsFlyer.trackEvent("Open_notification")
              analytics().logEvent('Open_notification', {
                value: '',
              });
              // alert(JSON.stringify(remoteMessage) )
    
                if (remoteMessage.data.url === "MixMatch") {
    
                  this.timer = setTimeout(() => {
                    this.props.navigation.push('MyClosetDetailPage', {
                      product_id: remoteMessage.data.push_id,
                      returnPage: 'Tabs',
                    })
                  }, 500);
                }
                if (remoteMessage.data.url === "StreetSnap") {
                  this.timer = setTimeout(() => {
                    this.props.navigation.navigate('PushlookbookStreetSnapPage', {
                      streetId: remoteMessage.data.push_id,
                      returnPage: 'Tabs',
                    })
                  }, 500);
                }
              }
    })
    

    Create Notification Service Extension

    If I want to send an iOS Push Notification with picture to my iPhone, I have to add the iOS Push Notification with Notification Service Extension.

    1. In the Xcode menu, go to File > New > Target.
    2. Select the Notification Service Extension.
    3. Gives the name the Extension service and click the finish button.

    and enable Push Notification and App Group capabilities in iOS App target.

    NotificationService.h

    #import <UserNotifications/UserNotifications.h>
    
    @interface NotificationService : UNNotificationServiceExtension
    
    @end
    

    NotificationService.m

    #import "NotificationService.h"
    @import Firebase;
    
    @interface NotificationService ()
    
    @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
    @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
    
    @end
    
    @implementation NotificationService
    
    - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
        self.contentHandler = contentHandler;
        self.bestAttemptContent = [request.content mutableCopy];
        
        // Modify the notification content here...
      if (self.bestAttemptContent.title) {
        self.bestAttemptContent.title = [NSString stringWithFormat:@"%@", self.bestAttemptContent.title];
      }
      [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent
      withContentHandler:contentHandler];
    }
    
    - (void)serviceExtensionTimeWillExpire {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        self.contentHandler(self.bestAttemptContent);
    }
    
    @end
    

    The format of Push Notification Service be sent by Server

    The content of data can be added or deleted with costume way. if your android device click the push notification bar, and then the app is not opened, the problem must be caused by the format of Push Notification Service. iOS as well.

    {
      "message": {
        "notification": {
          "title": "title",
          "body": "message content"
        },
        "token": "fi7FrXMCFeQ:APA91bEZ3CCZEu6NJCzPNyOXq3QoGuCgZ_NZ6pSkuvAYM-VKTvfj1FbnBQKimHaOVqWv_4FD_eGZn1CcfNRf2Ve6X4_mYNwmgI99A1ngxcnY6oyjXTcNRsdIh7YD3SizhRHoTbIXcn-8",
        "data": {
          "image_url": "",
          "push_type": "0",
          "type": "0",
          "url": "MixMatch",
          "push_id": "6587588",
          "send_user_history_id": ""
        },
        "apns": {
          "headers": {
            "apns-priority": "10"
          },
          "payload": {
            "aps": {
              "badge": 1,
              "mutable-content": 1
            }
          },
          "fcm_options": {
            "image": ""
          }
        }
      }
    }
    

    Detecting that notification is open or closed when app is in foreground or background.

    if we need to detect when our app is coming to the foreground or when it comes to background, the AppState will help me to do it so easy:

    
    import NotificationManager from 'react-native-check-notification-enable'
    
    constructor(props) {
        super(props);
        this.state = {
            loginShow: false,
            loginStatus: false,
            isEnabled: false,
        }
        this.flage = false
    }
    
    componentDidMount() {
        AppState.addEventListener('change',this._handleAppStateChange)
        this._navListener = this.props.navigation.addListener('didFocus', () => {
    
          if (Platform.OS === 'ios') {
            messaging().requestPermission().then((response: any) => {
                if (response === 1) {
                    this.setState(prevState => ({
                        isEnabled: true
                    }))
                }
                else {
                    this.setState(prevState => ({
                        isEnabled: false
                    }))
                }
            })
          }
          else {
            NotificationManager.areNotificationsEnabled().then((e)=>{
                if (e === true) {
                    this.setState(prevState => ({
                        isEnabled: true
                    }))
                }
                else {
                    this.setState(prevState => ({
                        isEnabled: false
                    }))
                }
              }).catch((e)=>{
                this.setState(prevState => ({
                    isEnabled: false
                }))
              })
          }
    
        })
    }
    
    _handleAppStateChange = (nextAppState) => {
        if (nextAppState != null && nextAppState === 'active') {
            //如果是true ,表示从后台进入了前台 ,请求数据,刷新页面。或者做其他的逻辑
            if (this.flage) {
                if (Platform.OS === 'ios') {
                    messaging().requestPermission().then((response: any) => {
                        if (response === 1) {
                            this.setState(prevState => ({
                                isEnabled: true
                            }))
                        }
                        else {
                            this.setState(prevState => ({
                                isEnabled: false
                            }))
                        }
                    })
                }
                else {
                    NotificationManager.areNotificationsEnabled().then((e) => {
                        if (e === true) {
                            this.setState(prevState => ({
                                isEnabled: true
                            }))
                        }
                        else {
                            this.setState(prevState => ({
                                isEnabled: false
                            }))
                        }
                    }).catch((e) => {
                        this.setState(prevState => ({
                            isEnabled: false
                        }))
                    })
                }
            }
            this.flage = false;
        } else if (nextAppState != null && nextAppState === 'background') {
            this.flage = true;
        }
    }
    
    
    _handleAppStateChange = (nextAppState) => {
        if (nextAppState != null && nextAppState === 'active') {
            //如果是true ,表示从后台进入了前台 ,请求数据,刷新页面。或者做其他的逻辑
            if (this.flage) {
                if (Platform.OS === 'ios') {
                    messaging().requestPermission().then((response: any) => {
                        if (response === 1) {
                            this.setState(prevState => ({
                                isEnabled: true
                            }))
                        }
                        else {
                            this.setState(prevState => ({
                                isEnabled: false
                            }))
                        }
                    })
                }
                else {
                    NotificationManager.areNotificationsEnabled().then((e) => {
                        if (e === true) {
                            this.setState(prevState => ({
                                isEnabled: true
                            }))
                        }
                        else {
                            this.setState(prevState => ({
                                isEnabled: false
                            }))
                        }
                    }).catch((e) => {
                        this.setState(prevState => ({
                            isEnabled: false
                        }))
                    })
                }
            }
            this.flage = false;
        } else if (nextAppState != null && nextAppState === 'background') {
            this.flage = true;
        }
    }
    

    相关文章

      网友评论

          本文标题:React native - Push Notification

          本文链接:https://www.haomeiwen.com/subject/bvpmwktx.html