React Native Setup

How to install the Airship React Native module.

Requirements

  • React Native >= 0.60.0
  • React Native cli >= 2.0.1

iOS

  • Xcode 15.3+
  • minimum deployment target iOS 14

Android

  • minSdkVersion 21+
  • compileSdkVersion 34+
  • Java 8

Standard React Native Setup

Install the plugin using yarn or npm:

yarn add @ua/react-native-airship

Android

  1. Compile and Target SDK Versions:

    Urban Airship now requires compileSdk version 34+ or higher.

    Please update the build.gradle file:

    android {
       compileSdkVersion 31
    
       defaultConfig {
             minSdkVersion 21
             targetSdkVersion 31
    
             // ...
       }
    }
  2. Java 8 Source Compatibility:

    Airship now requires Java 8 language features across all SDK modules.

    Please update Android Gradle Plugin to version 3.0.0 or higher and change the source and target compatibility for each module that uses Airship SDKs:

    android {
       compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_1_8
       }
    }

    Modules using Kotlin will also need to set the target version of the generated JVM bytecode:

    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach  {
       kotlinOptions {
          jvmTarget = JavaVersion.VERSION_1_8
       }
    }
  3. Download the Android Firebase configuration file google-services.json from the application’s Firebase console into the root directory at android/app/google-services.json.

    If your react-native application does not have an associated app in the Firebase console, follow the FCM setup instructions to set one up.

HMS setup

  1. Follow Huawei’s documentation to set up the HMS SDK.

     Note

    Airship requires HMS Core Push SDK 6.3.0.304 or newer.

  2. Add airshipHmsEnabled=true to the app’s gradle.properties.

iOS

  1. Install pods:

    $ pod install

  2. Open your app’s project in the generated .xcworkspace file, and add the following capabilities:

    • Push Notification
    • Background Modes > Remote Notifications
  3. To take advantage of notification attachments, such as images, animated gifs, and video, you will need to create a notification service extension.

    Follow the steps in the iOS Notification Service Extension Guide.

Expo Setup

Apps using Expo’s managed workflows can use the airship-expo-plugin to configure the project.

expo install airship-expo-plugin
yarn add @ua/react-native-airship

Configure the plugin

Add the plugin to the app.json with the app’s config:

"plugins":[
  [
    "airship-expo-plugin",
    {
      "android":{
        "icon": "./assets/ic_notification.png",
        "customNotificationChannels": "./assets/notification_channels.xml",
        "airshipExtender": "./assets/AirshipExtender.kt"
      },
      "ios":{
        "mode": "development",
        "notificationService": "./assets/NotificationService.swift",
        "notificationServiceInfo": "./assets/NotificationServiceExtension-Info.plist",
        "notificationServiceTargetName": "NotificationServiceExtension",
        "developmentTeamID": "MY_TEAM_ID",
        "airshipExtender": "./assets/AirshipPluginExtender.swift"
      }
    }
  ]
]

Android Config:

  • icon: Required. Local path to an image to use as the icon for push notifications. 96x96 all-white png with transparency. The name of the icon will be the resource name.
  • customNotificationChannels: Optional. The local path to a Custom Notification Channels resource file.
  • airshipExtender: Optional. The local path to a AirshipExtender.kt file.

iOS Config:

  • mode: Required. The APNS entitlement. Either development or production.
  • notificationService: Optional. The local path to a custom Notification Service Extension or DEFAULT_AIRSHIP_SERVICE_EXTENSION for Airship’s default one.
  • notificationServiceInfo: Optional. Airship will use a default one if not provided. The local path to a Notification Service Extension Info.plist.
  • notificationServiceTargetName: Optional. Defaults to NotificationServiceExtension if not provided.
  • developmentTeamID: Optional. The Apple Development Team ID used to configure the Notification Service Extension target.
  • airshipExtender: Optional. The local path to a AirshipPluginExtender.swift file.

Troubleshooting

If you don’t receive Airship pushes, make sure you didn’t previously install expo-notifications or another push provider by mistake. There can only be one service in each app that receives FCM messages, so it might create conflicts with Airship.

If you do want to have another push provider alongside Airship, you will need to create your own FirebaseMessagingService to forward onNewToken and onMessageReceived calls to the Airship SDK. Follow the steps for Extending the FirebaseMessagingService in the Android SDK Setup documentation.

Calling TakeOff

takeOff should be called in a standard application at the beginning of the lifecycle. Once takeOff is called, the config will be stored and applied for future app inits. If takeOff is called again with a different config, the new config will not be applied until the next app init.

import Airship from '@ua/react-native-airship';

Airship.takeOff({
    default: {
        appKey: "REPLACE_WITH_YOUR_APP_KEY",
        appSecret: "REPLACE_WITH_YOUR_APP_SECRET"
    },
    site: "us", // use "eu" for EU cloud projects
    urlAllowList: ["*"],
    android: {
        notificationConfig: {
            icon: "ic_notification",
            accentColor: "#00ff00"
        }
    }
});

URL Allowlist

The URL allowlist controls which URLs the Airship SDK is able to act on. The SDK divides up usages of URLs into three different config options:

  • urlAllowListScopeOpenUrl: Only URLs allowed for this scope can be opened from an action, displayed in landing page, displayed in an HTML in-app message, or displayed as media in an In-App Automation. Defaults to any Airship-originated URLs and YouTube URLs.
  • urlAllowListScopeJavaScriptInterface: These URLs are checked before the Airship JavaScript interface is injected into the webview. Defaults to any Airship-originated URLs
  • urlAllowList: Both scopes are applied to these URLs.
Valid URL pattern syntax
<pattern> := '*' | <scheme>'://'<host>/<path> | <scheme>'://'<host> | <scheme>':/'<path> | <scheme>':///'<path>
<scheme> := <any char combination, '*' are treated as wild cards>
<host> := '*' | '*.'<any char combination except '/' and '*'> | <any char combination except '/' and '*'>
<path> := <any char combination, '*' are treated as wild cards>

To accept any URL within the SDK, set the urlAllowList to ["*"].

Extending Airship

To access the underlying native SDK when Airship is ready, you can provide a plugin extender that will be automatically loaded for the app. This gives the app a chance to customize parts of Airship that are not configurable through React Native, and gives a place to setup iOS Live Activities and Android Live Updates

iOS

For iOS, create a Swift file named AirshipPluginExtender.swift and needs to be included in the main app target. Make sure the class has the @objc(AirshipPluginExtender) annotation and inherits AirshipPluginExtenderProtocol.

import Foundation
import AirshipKit
import AirshipFrameworkProxy
import ActivityKit

@objc(AirshipPluginExtender)
public class AirshipPluginExtender: NSObject, AirshipPluginExtenderProtocol {
  
  public static func onAirshipReady() {
   // Called when Airship is ready on the MainActor
  }

}

Android

Create a file in the App’s src directory named AirshipExtender. It needs to extend com.urbanairship.android.framework.proxy.AirshipPluginExtender and have an empty constructor.

// Replace with your package
package com.example

import android.content.Context
import androidx.annotation.Keep
import com.urbanairship.UAirship
import com.urbanairship.android.framework.proxy.AirshipPluginExtender

@Keep
public final class AirshipExtender: AirshipPluginExtender {

    override fun onAirshipReady(context: Context, airship: UAirship) {
        // Called when Airship is ready on a background thread. 
        // Avoid doing long running, blocking work or it will delay Airship
    }

}

Register the extender in the manifest:

<application ...>

    <meta-data android:name="com.urbanairship.plugin.extender"
        android:value="com.example.AirshipExtender" />

    <!-- ... -->
</application>

Implementation best practices

Make sure to set up logging. Internal logging can be valuable when troubleshooting issues that arise when testing.

Anytime you make any changes or updates to the SDK, test on a development device to ensure your integration was successful. Also make sure analytic information is still flowing to your Airship project before sending the app to production.