1.0.0 • Published 7 months ago

@questlabs/react-native-notifications v1.0.0

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

Quest Notifications for React Native

QuestNotifications is a React Native SDK that allows you to receive push notifications from campaigns created on the QuestLabs Dashboard. Simply integrate this package into your app, and it will handle incoming notifications for all campaigns configured through the dashboard.

Installation

QuestNotifications relies on Firebase Cloud Messaging (FCM) for receiving remote notifications and Notifee for displaying them. You must install these packages as well.

npm install @questlabs/react-native-notifications @notifee/react-native @react-native-firebase/app @react-native-firebase/messaging

Configuration

Before using the QuestNotifications SDK, you need to configure Firebase Cloud Messaging (FCM) properly. FCM is essential for handling remote notifications, and without the correct setup, notifications won't work.

Firebase Setup

  1. Create a Firebase Project:

    • Go to the Firebase Console.
    • Click on "Add Project" and follow the prompts to create a new Firebase project.
    • Once your project is created, click on the "Settings" gear icon and select "Project settings."
    • In the "Your apps" section, click on the Android or iOS icon to add your app to Firebase.
    • Follow the instructions to download the google-services.json file for Android or the GoogleService-Info.plist file for iOS.
  2. Configure Service Account on QuestLabs Dashboard:

    • In the Firebase Console, go to "Project settings" and select the "Service accounts" tab.
    • Click on "Generate new private key" to download a JSON file containing your service account credentials.
    • Now go to QuestLabs Dashboard Integrations and add service account credentials there. Or you can use existing integrated service account on the dashboard.
  3. Service Account Authorization:

    • Service account must have roles Firebase Admin and Firebase messaging Admin.
    • To add roles to service account, go to Cloud Console IAM and add required roles.

React Native CLI

This SDK is primarily designed for React Native CLI, but it can still be used with Expo.

Android

  • Place the google-services.json file in the android/app directory of your React Native project.
  • Add the following lines to your android/build.gradle file:
     buildscript {
         dependencies {
             // ... other dependencies
             classpath 'com.google.gms:google-services:4.4.2' // Add this line
         }
     }
  • Add the following line to your android/app/build.gradle file:
     apply plugin: 'com.google.gms.google-services' // Add this line

IOS

  • Using Xcode, open the projects /ios/{projectName}.xcodeproj file (or /ios/{projectName}.xcworkspace using Pods).
  • Right click on the project name and "Add files" to the project.
  • Select the GoogleService-Info.plist file and add it to the project.
  • Add the following lines to your /ios/{projectName}/AppDelegate.swift file (React Native 0.77+):

     // ... other imports
     import Firebase // Add this line after `import ReactAppDependencyProvider`
    
     override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
         FirebaseApp.configure() // Add this line at the top
         // ... other code
     }
  • Add the following lines to your /ios/{projectName}/AppDelegate.m file (React Native 0.76 and below):

     // ... other imports
     #import <Firebase.h> // Add this line after `#import "AppDelegate.h"`
    
     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
         [FIRApp configure]; // Add this line at the top
         // ... other code
     }
  • Altering CocoaPods to use frameworks

    • Beginning with firebase-ios-sdk v9+ (react-native-firebase v15+) you must tell CocoaPods to use frameworks.
    • Add the following line to your ./ios/Podfile:

      use_frameworks! :linkage => :static # Add this line after the `use_react_native`
      $RNFirebaseAsStaticFramework = true # Add this line to use Static Frameworks on iOS

      Notes: React-Native-Firebase uses use_frameworks, which has compatibility issues with Flipper & Fabric.

      Flipper: use_frameworks is not compatible with Flipper. You must disable Flipper by commenting out the :flipper_configuration line in your Podfile. Flipper is deprecated in the react-native community and this will not be fixed - Flipper and react-native-firebase will never work together on iOS.

      New Architecture: Fabric is partially compatible with use_frameworks!. If you enable the bridged / compatibility mode, react-native-firebase will compile correctly and be usable.

Expo

Expo requires additional configuration to use this package, and it works only with development builds.

Android

  • Place the google-services.json file in the root directory of your Expo project.
  • Enter file path in your app.json > expo > android > googleServicesFile
  • Add @react-native-firebase/app to your app.json > expo > plugins
{
  "expo": {
    // ... other configurations
    "android": {
      // ... other android configurations
      "googleServicesFile": "./google-services.json"
    },
    "plugins": [
      // ... other plugins
      "@react-native-firebase/app"
    ]
  }
}

Note: You need to run your app in a development build to use this package. Installing Notifee package could cause build failure for expo applications because it doesn't have plugins to configure maven directory. If it doesnt work for you, you may try this solution:

Create a custom plugin file in root directory of your project /plugins/notifee.js

const { withProjectBuildGradle } = require('@expo/config-plugins');

const notifee = (config) => {
  return withProjectBuildGradle(config, (config) => {
    if (config.modResults.contents.includes('@notifee/react-native')) {
      return config;
    }
    config.modResults.contents = config.modResults.contents.replace(
      /allprojects\s*{[^}]+repositories\s*{/,
      (match) => `${match}\n        maven { url "\${rootDir}/../node_modules/@notifee/react-native/android/libs" }`
    );

    return config;
  });
};

module.exports = notifee;

Add this plugin to your app.json > expo > plugins

{
  "expo": {
    // ... other configurations
    "plugins": [
      // ... other plugins
      "./plugins/notifee"
    ]
  }
}

IOS

  • Place the GoogleService-Info.plist file in the root directory of your Expo project.
  • Install npx expo install expo-build-properties
  • Update your app.json file with the following configuration:
    {
      "expo": {
        // ... other configurations
        "ios": {
          // ... other ios configurations
          "bundleIdentifier": "<YOUR_BUNDLE_IDENTIFIER>",
          "appleTeamId": "<YOUR_APPLE_TEAM_ID>",
          "googleServicesFile": "./GoogleService-Info.plist"
          "entitlements": {
             "aps-environment": "development" | "production"
          },
          "infoPlist": {
             "UIBackgroundModes": [
                 "fetch",
                 "remote-notification"
             ]
          }
        },
        "plugins": [
          // ... other plugins
          "@react-native-firebase/app",
          [
             "expo-build-properties",
             {
               "ios": {
                 "useFrameworks": "static"
               }
             }
          ]
        ]
      }
    }

IOS Additional Configuration

Now we have to generate certificates and update it in firebase console to enable your app to receive remote notifications.

  • You must have an active Apple Developer Account
  • Open your project's workspace file via Xcode, and navigate to Project > Targets > Signing & Capabilities tab.
  • Click on the + Capability button to add a new capability. Select Push Notifications & Background Modes from the list (If no option appears when searching, the capability may already be enabled).\
  • Then expand the Background Modes capability and enable Background fetch and the Remote notifications.

  • Linking APNs with FCM required following steps:

    • Registering a key.
    • Go to Apple Developer Account Keys and create a new key. Select Apple Push Notifications service (APNs) from the list.
    • Download the key and save it in a safe place.
    • Now go to Firebase Console and go to Project settings > Cloud Messaging.
    • Select Apple App and Upload the key you downloaded earlier and save it.
  • Registering an App Identifier.
    • Go to Apple Developer Account Identifiers and create a new App Identifier. Select App IDs from the list.
    • Select Explicit and enter your Bundle ID.
    • In Capabilities section, enable Push Notifications & Push Notifications > Broadcast Compatibility.
    • Save the App Identifier.
    • Now go to Xcode and select your project. Go to Project > Targets > Signing & Capabilities tab. enter your App Identifier in the Bundle Identifier field.
  • Generating a provisioning profile (Optional). - Go to Apple Developer Account Provisioning Profiles and create a new provisioning profile. Select iOS App Development from the list. - Select your App Id and your Development Certificate, select your device. - Download the provisioning profile and save it in a safe place. - Now go to Xcode and select your project. Go to Project > Targets > Signing & Capabilities tab. Select your provisioning profile in the Provisioning Profile field. Follow the official Firebase documentation for more detailed instructions.

Usage

First, you need to create a Push Notification campaign on the QuestLabs Dashboard with your target audience to receive the notifications.

You have to initialize the SDK in your app's entry point, most likely index.js or App.js (required for background notifications):

import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import { initialize } from '@questlabs/react-native-notifications';

// Initialize the SDK
// Note: You can create multiple instances of the SDK with different configurations, the default instance id is 'default'

initialize({
    apiKey: '<YOUR_API_KEY>',
    entityId: '<YOUR_ENTITYID>', 
    apiType: '<STAGING | PRODUCTION>',
    questUserId: '<QUEST_USER_ID>',
    authenticationToken: '<YOUR_AUTHENTICATION-_TOKEN>'
});


AppRegistry.registerComponent(appName, () => App);

Then you have to register the user to receive notifications. You can do this by calling the register method on the notifications object. You can also unregister the user by calling the unregister method.

import { useEffect, View, Text, Button } from 'react-native'
import { notifications } from '@questlabs/react-native-notifications';

function App(){
    const [user, setUser] = useState(null)

    const signIn = async () => {
        const user = { id: 1, name: 'John Doe' }

        // These configurations are optional, you can also pass them in the initialize method
        // notifications().configure({
        //     questUserId: user.id, // Required if externalUserId is absent
        //     externalUserId: user.id, // Required if questUserId is absent
        // })

        await notifications().register() // (Make sure register every instance one by one)
        setUser({ name: 'John Doe' })
    }

    const signOut = async () => {
        await notifications().unregister()
        setUser(null)
    }
    
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            {user ? (
                <>
                    <Text>Welcome, {user.name}!</Text>
                    <Button 
                        title="Sign Out"
                        onPress={signOut} 
                    />
                </>
            ) : (
                <Button 
                    title="Sign In"
                    onPress={signIn} 
                />
            )}
        </View>
    )
}

API Reference

The QuestNotifications SDK provides the following methods:

MethodDescription
initialize(configuration, instanceId?)Initializes the QuestNotifications instance with the provided configuration, and returns an instance of the QuestNotifications.
isInitialized(instanceId?)Checks if the QuestNotifications instance is initialized.
destroy(instanceId?)Destroys the QuestNotifications instance.
notifications(instanceId?)Returns an instance of the QuestNotifications.

Configuration Properties

The SDK initialization requires a configuration object with the following properties:

PropertyTypeDescriptionDefault
apiKeystringAPI key for authentication (Required).None (Required)
apiType'STAGING' | 'PRODUCTION'Specifies the API environment.'PRODUCTION'
entityIdstringUnique identifier for the entity (Required).None (Required)
authenticationTokenstringToken used for authentication (Required).None (Required)
questUserIdstringInternal user ID (Required if externalUserId is absent).None (Required)*
externalUserIdstringExternal user ID (Required if questUserId is absent).None (Required)*
defaultNotificationOptionsNotificationDefault options for notifications.{ title: 'QuestLabs', body: 'No body', android: { channelId: 'default' }, ios: { summaryArgument: 'QuestLabs', summaryArgumentCount: 1, foregroundPresentationOptions: { alert: true, badge: true, banner: true, sound: true } } }
defaultChannelOptionsAndroidChannelDefault options for Android notification channels.{ id: 'default', name: 'Default Channel', importance: HIGH }
defaultCategoryOptionsIOSNotificationCategoryDefault options for iOS notification categories.{ id: 'default', summaryFormat: 'You have %u+ unread messages from %@' }
settings.disableTrackingbooleanWhether to disable tracking.false
settings.disableNotificationDisplaybooleanWhether to prevent notifications from being displayed.false
settings.registerDeviceForRemoteNotificationsbooleanWhether to register the device for remote notifications, Not required with auto-linking. (iOS only)false

Note: Either questUserId or externalUserId must be provided, but not both.

Methods

The following methods are provided by notifications instance:

MethodDescription
configure(config)Updates the SDK configuration with the provided values.
requestPermissions()Requests permissions for push notifications. Returns true if granted, otherwise false.
getToken()Retrieves the FCM token for the user. Returns a string.
register()Registers the user for FCM push notifications. Returns a Promise<void>.
unregister()Unregisters the user from FCM push notifications. Returns a Promise<void>.
destroy()Destroys the SDK instance.
on(type, callback)Adds an event listener for a specific event type. Returns an unsubscribe function.
__updateToken(token?)Updates the user's FCM token in QuestLabs backend. Rarely required to be called manually.
__removeToken(token?)Removes the user's FCM token from QuestLabs backend. Rarely required to be called manually.
__displayNotification(remoteMessage)Displays a notification using Notifee. Rarely required to be called manually.
__flush()Flushes all cleanup functions. Rarely required to be called manually.
__emitEvent(type, eventDetail)Emits an event to all event listeners for a specific event type. Rarely required to be called manually.
__notifeeEventHandler()Handles Notifee events. Rarely required to be called manually.
__fcmEventHandler()Handles FCM events. Rarely required to be called manually.

Note: Methods that start with __ are not private, but users generally don't need to call them manually. They are only useful in rare cases where deeper customization is needed.

Contact Us

If you encounter any issues or have questions while using the QuestNotifications React SDK, please don't hesitate to reach out to us:

Shubham - shubham@questapp.xyz

Deb - shubham@questapp.xyz

License

This project is licensed under the MIT License.