2.1.0 • Published 2 months ago

smartpush-sdk-react v2.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 months ago

Pluggable's Smartpush Plugin for React Native apps

A React Native plugin for React Native apps.

Pre-conditions Integrate with FCM

Before using this plugin you should guarantee that your app already integrates with React Native Firebase and then with Firebase Cloud Messaging (FCM). The steps are quite easy to follow.

  1. Create a new Firebase project. Note that current versions of firebase-ios-sdk have a minimum Xcode requirement of 14.1, which implies a minimum macOS version of 12.5 (macOS Monterey);

  2. Install the React Native Firebase "app" module to the root of the React Native project with NPM: npm install --save @react-native-firebase/app. The @react-native-firebase/app module must be installed before using any other Firebase service;

  3. Android Setup - a configuration file must be downloaded and added to the project:

  • On the Firebase console, add a new Android application and enter the projects details. The "Android package name" must match the local projects package name which can be found inside of the manifest tag within the /android/app/src/main/AndroidManifest.xml file within the project;
  • Download the google-services.json file and place it inside of the project at the following location: /android/app/google-services.json;
  • To allow Firebase on Android to use the credentials, the google-services plugin must be enabled on the project. This requires modification to two files in the Android directory. First, add the google-services plugin as a dependency inside of the /android/build.gradle file:
    buildscript {
      dependencies {
        // ... other dependencies
        classpath 'com.google.gms:google-services:4.3.15'
      }
    }
  • Lastly, execute the plugin by adding the following to the /android/app/build.gradle file:
    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services' // <- Add this line 
  1. iOS Setup - to allow the iOS app to securely connect to the Firebase project, a configuration file must be downloaded and added to the project, and you must enable frameworks in CocoaPods:
  • On the Firebase console, add a new iOS application and enter your projects details. The "Apple bundle ID" must match your local project bundle ID. The bundle ID can be found within the "General" tab when opening the project with Xcode;
  • Download the GoogleService-Info.plist file;
  • Using Xcode, open the projects /ios/{projectName}.xcodeproj file (or /ios/{projectName}.xcworkspace if using Pods) and right click on the project name and "Add files" to the project. Select the downloaded GoogleService-Info.plist file from your computer, and ensure the Copy items if needed checkbox is enabled;
  • To allow Firebase on iOS to use the credentials, the Firebase iOS SDK must be configured during the bootstrap phase of your application. To do this, open your /ios/{projectName}/AppDelegate.mm file (or AppDelegate.m if on older react-native), and add the following:
    #import "AppDelegate.h"
    #import <Firebase.h> // <- Add this line
    // ...
  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { // Add me --- \/ FIRApp configure; // <- Add this line // Add me --- /\ // ... } // ...
  • Beginning with firebase-ios-sdk v9+ (react-native-firebase v15+) you must tell CocoaPods to use frameworks. Open the file ./ios/Podfile and add the following line inside your targets (right after the line calling the react native Podfile function to get the native modules config):
    target 'reactnativeapp' do
      config = use_native_modules!
      use_frameworks! :linkage => :static # <- Add this line
      $RNFirebaseAsStaticFramework = true # <- Add this line (see next point)
      ...
      # Note that if you have use_frameworks! enabled, Flipper will not work and
      # you should disable the next line.
      #:flipper_configuration => flipper_config, # <- COMMENT this line
      ...
  • To use Static Frameworks on iOS, you also need to manually enable this for the project with the following global to your ./ios/Podfile file:
    # right after `use_frameworks! :linkage => :static`
    $RNFirebaseAsStaticFramework = true
  1. Once the above steps have been completed, the React Native Firebase library must be linked to the project and the application needs to be rebuilt. Users on React Native 0.60+ automatically have access to "autolinking", requiring no further manual installation steps. To automatically link the package, rebuild your project (for manual linking, if you're using an older version of React Native without autolinking support, or wish to integrate into an existing project, you can follow the manual installation steps for iOS and Android):

    # Android apps
    npm run android
    
    # iOS apps
    cd ios/
    pod install --repo-update
    cd ..
    npm run ios
  2. You can now install the messaging module by running:

    # Install the messaging module
    npm install @react-native-firebase/messaging
    
    # If you're developing your app using iOS, run this command
    cd ios/ && pod install
    
    cd ..
    npm run ios
  3. iOS Setup - iOS requires further configuration before you can start receiving and sending messages through Firebase. Read the documentation and follow the steps on how to setup iOS with Firebase Cloud Messaging.

NOTE: FCM via APNs does not work on iOS Simulators. To receive messages & notifications a real device is required. The same is recommended for Android. Also, for iOS, React-Native-Firebase uses use_frameworks, which has compatibility issues with Flipper, Hermes, and Fabric.

Smartpush Usage

After configuring your app to integrate with FCM, you are ready to use this plugin to properly engage with your users. To install the plugin just:

  1. First install the Smartpush Package by running npm install smartpush-sdk-react in the root of the project;

  2. Once the above steps have been completed, the React Native Firebase library must be linked to your project and your application needs to be rebuilt. Users on React Native 0.60+ automatically have access to "autolinking", requiring no further manual installation steps. To automatically link the package, rebuild your project:

    # Android apps
    npm run android
    
    # iOS apps
    cd ios/
    pod install --repo-update
  3. OPTIONAL: For iOS, if you want to display push notifications while your app is in the foreground, you must allow that specific scenario:

  • In your app's AppDelegate.h file:

    // Import the native iOS UserNotifications package
    #import <UserNotifications/UserNotifications.h> // <- Add this line
    
    // Extend the UNUserNotificationCenterDelegate class
    @interface AppDelegate : RCTAppDelegate<UNUserNotificationCenterDelegate> // <- Update this line
  • In your app's AppDelegate.mm file:

    // Import the native iOS UserNotifications package
    #import <UserNotifications/UserNotifications.h> // <- Add this line
    
    // ...
  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { // ... UNUserNotificationCenter currentNotificationCenter.delegate = self; // <- Add this line // ... }

    // ...

    // Function to implement to display foreground push notifications

  • (void)userNotificationCenter:(UNUserNotificationCenter )center willPresentNotification:(UNNotification )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound); }

  1. NOTE that for Android, to customize the used notification icon just add the desired icon in the Android's drawble folder and name it ic_push_app_icon. Otherwise, a default icon, not related to your app, will be used.

  2. Finally, this library exposes two mandatory methods, which can be imported and used like this in, for example, your App.tsx file:

    ...
    import { 
        pluggableExecute, 
        pluggableStoreFeedback
     } from 'smartpush-sdk-react';
    ...
  • The pluggableExecute method is used to deliver the notification to the user. It autonomously executes the artificial intelligence models that deliveres the notification when the user is engaged:

    // Register background handler
    messaging().setBackgroundMessageHandler(async remoteMessage => {
        console.log('BACKGROUND: A new FCM message arrived!', remoteMessage);
        Alert.alert('BACKGROUND: A new FCM message arrived!', JSON.stringify(remoteMessage));
        const notifData = remoteMessage.data as {[key: string]: string};
        pluggableExecute(notifData).then(pushUUID => {
            console.log('[UUID]: ', pushUUID);
            // Save the pushUUID and (your) userID to your database if you want to create mapping records
            // ...
        });
    });
    // Register foreground handler
    function App(): JSX.Element {
        ...
        // To listen to messages in the foreground, call the onMessage method inside your application code. 
        useEffect(() => {
            messaging().onMessage(async remoteMessage => {
                console.log('FOREGROUND: A new FCM message arrived!', remoteMessage);
                Alert.alert('FOREGROUND: A new FCM message arrived!', JSON.stringify(remoteMessage));
                const notifData = remoteMessage.data as {[key: string]: string};
                pluggableExecute(notifData).then(pushUUID => {
                    console.log('[UUID]: ', pushUUID);
                    // Save the pushUUID and (your) userID to your database if you want to create mapping records
                    // ...
                });
            });
        }, []);
        ...
    }
  • The pluggableStoreFeedback and the pluggableClickFeedback methods are used to create engagement metrics, being called every time a notification is clicked. In addition, all extras sent in this notification (for deep linking, for example) are availabe in the remoteMessage.data dictionary:

    // When a non-remote push is clicked
    React.useEffect(() => {
        pluggableClickFeedback(event => {
            console.log('Feedback received!');
            // Handle the event, if required - it will open your main view.
        })
    })
    
    // When a remote push is clicked
    function App(): JSX.Element {
        ...
        useEffect(() => {
            // When the application is opened from a quit state, check whether an initial notification is available:
            messaging().getInitialNotification().then(remoteMessage => {
                if (remoteMessage) {
                    console.log('CLICKED NOTIFICATION:', remoteMessage.notification);
                    const notifData = remoteMessage.data as {[key: string]: string};
                    pluggableStoreFeedback(notifData);
                }
            });
            // When the application is running, but in the background:
            messaging().onNotificationOpenedApp(remoteMessage => {
                console.log('CLICKED NOTIFICATION:', remoteMessage.notification);
                const notifData = remoteMessage.data as {[key: string]: string};
                pluggableStoreFeedback(notifData);
            });
        }, []);
        ...
    }
  • For iOS there is the need to open your /ios/{projectName}/AppDelegate.mm file (or AppDelegate.m if on older react-native), and add the following:

    // Import the Smartpush Plugin
    #import <smartpush_sdk_react-Swift.h> // <- Add this line
    
    // ...
  • (void)userNotificationCenter:(UNUserNotificationCenter )center didReceiveNotificationResponse:(UNNotificationResponse )response withCompletionHandler:(void (^)(void))completionHandler { // Notification data NSDictionary userInfo = response.notification.request.content.userInfo; // Handle notification NSString pushId = userInfo@"pluggable_notification_key"; if ([pushId isKindOfClass:NSString class]) { SmartpushSdkReact iosStoreFeedbackWithPushId:pushId; } // Returning the preferred presentation option completionHandler(); }
  1. Three additional methods are exposed by the library to handle topics (aka segments) subscriptions and can be used, if needed, as follows:
    ...
    import { 
        pluggableSubscribeTopic, 
        pluggableUnsubscribeTopic, 
        pluggableGetSubscribedTopics
     } from 'smartpush-sdk-react';
    ...
  • You may want to send notifications to specific devices/users. For that, you need to know the FCM registration token associated with each device. To know that, you need to add the following methods:

    // Main call and Get user token 
    async function onAppBootstrap() {
        // Get the device token
        messaging().getToken().then(token => {
            console.log('TOKEN is:', token);
            // Store the FCM registration token in our app server
        });
        // Listen to whether the token changes
        messaging().onTokenRefresh(token => {
            console.log('TOKEN refreshed to:', token);
            // Store the FCM registration token in our app server
        });
    }
  • You can subscribe your client's app to a particular topic - the client will then receive notifications that are sent to that particular topic. You should call the pluggableSubscribeTopic method to let the SDK subscribe the user to that topic. This returns 1, if success, otherwise an error message. For that, you must do as follows:

    const USER_API_NAME = "YOUR_API_USERNAME"
    const USER_API_KEY = "YOUR_API_KEY"
    const PROMOTIONS_NOTIFICATION_TOPIC = "some_topic"
    
    pluggableSubscribeTopic(USER_API_NAME, USER_API_KEY, PROMOTIONS_NOTIFICATION_TOPIC, token).then(result => {
        console.log('[RESULT]: ', result);
    });
  • You can also unsubscribe your client's app from a particular topic. You should call the pluggableUnsubscribeTopic method to let the SDK unsubscribe the user from that topic. This returns 1, if success, otherwise an error message. For that, you must do as follows:

    pluggableUnsubscribeTopic(USER_API_NAME, USER_API_KEY, PROMOTIONS_NOTIFICATION_TOPIC, token).then(result => {
        console.log('[RESULT]: ', result);
    });
  • To get the list of topics the user is currently subscribed to you should call the pluggableGetSubscribedTopics method. This returns an array of strings. For that, you must do as follows:

    pluggableGetSubscribedTopics(USER_API_NAME, USER_API_KEY, token).then(resultArray => {
        console.log('[RESULT]: ', resultArray);
    });
  1. Three additional methods are exposed by the library to handle internal permissions (you are still required to ask the user for PUSH NOTIFICATION permission) and can be used, if needed, as follows:
    ...
    import {PermissionsAndroid} from 'react-native';
    import { 
        pluggableEnableInternalPushPermission,
        pluggableDisableInternalPushPermission,
        pluggableGetPushPermissionState
     } from 'smartpush-sdk-react';
    ...
  • To ask for the OS permission, you can do as follows:

    const requestPushPermission = async () => {
        try {
            // Request PUSH permission iOS
            const authStatus = await messaging().requestPermission();
            const enabled =
                authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
                authStatus === messaging.AuthorizationStatus.PROVISIONAL;
            if(enabled){
                console.log('Authorization status:', authStatus);
            }
            // Request PUSH permission ANDROID
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
                {
                    title: 'Cool push notifications?',
                    message:
                        'Do you want to receive ' +
                        'cool push notifications with lots of promotions?',
                    buttonNeutral: 'Ask Me Later',
                    buttonNegative: 'Cancel',
                    buttonPositive: 'OK',
                },
            );
            if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                console.log('You can use pushes.');
            } else {
                console.log('Push permission denied');
            }
        } catch (err) {
            console.warn(err)
        }
    }
  • Finally, the three additional methods that allows you to internally enable/disable push notifications (without disabling the OS permission itself) are the pluggableEnableInternalPushPermission, pluggableDisableInternalPushPermission, and pluggableGetPushPermissionState. These methods return 0, if the push permissions is disabled, 1, if the push permission is enabled, and -1, meaning that the user did not grant the required OS permission for push notifications. You can use these as follows:

    pluggableEnableInternalPushPermission().then(result => {
        console.log('[RESULT]: ', result);
    });
    
    pluggableDisableInternalPushPermission().then(result => {
        console.log('[RESULT]: ', result);
    });
    
    pluggableGetPushPermissionState().then(result => {
        console.log('[RESULT]: ', result);
    });

More info

  • For full compatibility, attention to the used versions of XCODE, SWIFT and COCOAPODS. Recommended versions are XCODE=15, SWIFT=5.9, and COCOAPODS=1.14.2.

  • For more info visit https://pluggableai.xyz/ or give us feedback to info@pluggableai.xyz.

2.1.0

2 months ago

2.1.0-beta.5

2 months ago

2.1.0-beta.7

2 months ago

2.1.0-beta.6

2 months ago

2.1.0-beta.3

2 months ago

2.1.0-beta.2

2 months ago

2.1.0-beta.4

2 months ago

2.1.0-beta.1

2 months ago

2.1.0-beta.0

2 months ago

1.8.14

4 months ago

1.8.14-beta.2

4 months ago

1.8.14-beta.1

4 months ago

1.8.14-beta.0

4 months ago

1.8.13

4 months ago

1.8.12-beta.0

4 months ago

1.8.12

4 months ago

1.8.11

5 months ago

1.8.9

7 months ago

1.8.10

6 months ago

1.8.8

7 months ago

1.8.7

7 months ago

1.8.6

7 months ago

1.8.5

7 months ago

1.8.4

7 months ago

1.8.3

7 months ago

1.8.2

8 months ago

1.0.4

8 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago