@questlabs/react-native-notifications v1.0.0
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/messagingConfiguration
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
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.jsonfile for Android or theGoogleService-Info.plistfile for iOS.
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.
Service Account Authorization:
- Service account must have roles
Firebase AdminandFirebase messaging Admin. - To add roles to service account, go to Cloud Console IAM and add required roles.
- Service account must have 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.jsonfile in theandroid/appdirectory of your React Native project. - Add the following lines to your
android/build.gradlefile: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.gradlefile:apply plugin: 'com.google.gms.google-services' // Add this line
IOS
- Using Xcode, open the projects
/ios/{projectName}.xcodeprojfile (or/ios/{projectName}.xcworkspaceusing Pods). - Right click on the project name and "Add files" to the project.
- Select the
GoogleService-Info.plistfile and add it to the project. Add the following lines to your
/ios/{projectName}/AppDelegate.swiftfile (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.mfile (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 iOSNotes: 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.jsonfile in the root directory of your Expo project. - Enter file path in your
app.json > expo > android > googleServicesFile - Add
@react-native-firebase/appto yourapp.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.jsconst { 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.plistfile in the root directory of your Expo project. - Install
npx expo install expo-build-properties - Update your
app.jsonfile 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 & Capabilitiestab. - Click on the
+ Capabilitybutton to add a new capability. SelectPush Notifications&Background Modesfrom the list (If no option appears when searching, the capability may already be enabled).\ Then expand the
Background Modescapability and enableBackground fetchand theRemote 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 Appand 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 IDsfrom the list. - Select
Explicitand 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 & Capabilitiestab. enter your App Identifier in theBundle Identifierfield.
- Go to Apple Developer Account Identifiers and create a new App Identifier. Select
- Generating a provisioning profile (Optional).
- Go to Apple Developer Account Provisioning Profiles and create a new provisioning profile. Select
iOS App Developmentfrom 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 toProject > Targets > Signing & Capabilitiestab. Select your provisioning profile in theProvisioning Profilefield. 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:
| Method | Description |
|---|---|
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:
| Property | Type | Description | Default |
|---|---|---|---|
apiKey | string | API key for authentication (Required). | None (Required) |
apiType | 'STAGING' | 'PRODUCTION' | Specifies the API environment. | 'PRODUCTION' |
entityId | string | Unique identifier for the entity (Required). | None (Required) |
authenticationToken | string | Token used for authentication (Required). | None (Required) |
questUserId | string | Internal user ID (Required if externalUserId is absent). | None (Required)* |
externalUserId | string | External user ID (Required if questUserId is absent). | None (Required)* |
defaultNotificationOptions | Notification | Default 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 } } } |
defaultChannelOptions | AndroidChannel | Default options for Android notification channels. | { id: 'default', name: 'Default Channel', importance: HIGH } |
defaultCategoryOptions | IOSNotificationCategory | Default options for iOS notification categories. | { id: 'default', summaryFormat: 'You have %u+ unread messages from %@' } |
settings.disableTracking | boolean | Whether to disable tracking. | false |
settings.disableNotificationDisplay | boolean | Whether to prevent notifications from being displayed. | false |
settings.registerDeviceForRemoteNotifications | boolean | Whether to register the device for remote notifications, Not required with auto-linking. (iOS only) | false |
Note: Either
questUserIdorexternalUserIdmust be provided, but not both.
Methods
The following methods are provided by notifications instance:
| Method | Description |
|---|---|
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.
7 months ago