React Native

Official @daertech/pushtifly-react-native SDK on top of @react-native-firebase/messaging, or integration via REST.

The official SDK @daertech/pushtifly-react-native works with React Native 0.76 or later, with the new architecture. It builds on @react-native-firebase/messaging and adds:

  • device registration, with an offline queue;
  • the Android channel;
  • notifications while the app is open on Android, with image and buttons, without Notifee;
  • reported opens and clicks, including the tapped button on iOS, which RNFB doesn't report;
  • users, tags and topics.

The token is FCM on both platforms. You need:

Using Expo? See Expo.

Installation

npm install @daertech/pushtifly-react-native @react-native-firebase/app @react-native-firebase/messaging
cd ios && pod install
  • Android: add google-services.json in android/app/, as RNFB explains.
  • iOS: add GoogleService-Info.plist, enable Push Notifications and Background Modes > Remote notifications. RNFB requires use_frameworks! :linkage => :static in the Podfile.

Usage

import { Pushtifly } from '@daertech/pushtifly-react-native';

// Outside components, once at startup
Pushtifly.init({
  appKey: 'pk_live_YOUR_PUBLIC_KEY',       // PUBLIC key only
  androidChannel: { id: 'general', name: 'General notices' },
});

Pushtifly.onNotificationOpened((n) => {
  // n.deepLink, n.actionId (tapped button), n.data (your data)
  if (n.deepLink) Linking.openURL(n.deepLink);
});

// Ask for permission once the user understands what it's for (on Android 13+ it asks for POST_NOTIFICATIONS)
const state = await Pushtifly.requestPermission();

Pushtifly.identify('customer-123');          // on sign-in
Pushtifly.setTags({ plan: 'gold' });
Pushtifly.subscribe('offers');
Pushtifly.logout();                          // on sign-out

You can subscribe to onNotificationOpened before init. If the app was opened from a notification, the open is still delivered.

Calls don't wait for the network: they're stored in a persistent queue. They're sent when there's a token and a connection, and retried when the user comes back to the app.

init options

Option Default Description
appKey — Public key pk_live_… or pk_test_…. The SDK rejects secret keys.
appId — Only if the key isn't restricted to one app.
autoRegister false Ask for permission at launch.
foregroundDisplay true Show notifications while the app is open.
androidChannel — Channel the SDK creates; it must match the app's default channel in Pushtifly.
iosNotificationServiceExtension false The app includes the extension (see below).
debug false Logs in the console.

On iOS, notifications while the app is open are shown by the system according to messaging_ios_foreground_presentation_options in RNFB's firebase.json.

Test device

await Pushtifly.pairTestDevice('483920');   // 6-digit code from the Devices section

Images and buttons on iOS

  1. In Xcode: File > New > Target > Notification Service Extension.
  2. Replace its NotificationService.swift with node_modules/@daertech/pushtifly-react-native/ios/NotificationService/NotificationService.swift.
  3. Start the SDK with iosNotificationServiceExtension: true.

With Expo, the SDK's plugin does these steps for you.

A send with a carousel (2 to 5 images) looks like this with the SDK; without these steps, the phone shows only the first image.

Android

The carousel arrives as a data message and the SDK draws it, even when the app is closed. Register the background handler in index.js (outside your components) and turn on androidCarousel:

import { getMessaging, setBackgroundMessageHandler } from '@react-native-firebase/messaging';
import { Pushtifly } from '@daertech/pushtifly-react-native';

setBackgroundMessageHandler(getMessaging(), async (message) => {
  await Pushtifly.handleBackgroundMessage(message);
});

Pushtifly.init({ appKey: 'pk_live_…', androidCarousel: true });

iOS

The carousel needs, besides the Service Extension, a Notification Content Extension:

  1. In Xcode: File > New > Target > Notification Content Extension.
  2. Replace its NotificationViewController.swift and Info.plist with the package's: node_modules/@daertech/pushtifly-react-native/ios/NotificationContent/. Delete the generated MainInterface.storyboard.
  3. Also use the updated Service Extension template (node_modules/@daertech/pushtifly-react-native/ios/NotificationService/): it downloads all the images.
  4. Start the SDK with iosNotificationServiceExtension: true and iosNotificationContentExtension: true.

On long press the carousel appears; the View button opens the app with the visible image's link.

Firebase Installation ID

If you turn on Firebase's Installation ID mode in the app, the SDK detects it and registers the FID instead of the registration token, with no changes to your code. See Firebase Installation ID.

What the SDK reports

Event When
received The notification arrives while the app is open.
opened The user taps the notification.
clicked The user taps a button (includes actionId).
permission_granted / permission_denied The permission changes.

Without the SDK (REST)

import { getMessaging, getToken } from '@react-native-firebase/messaging';

const token = await getToken(getMessaging());
await fetch('https://api.pushtifly.com/v1/devices', {
  method: 'POST',
  headers: { Authorization: 'Bearer pk_live_YOUR_PUBLIC_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ token, platform: Platform.OS, provider: 'fcm', framework: 'react_native' }),
});

The send's id arrives in data._phid and the link in data.deepLink. Report it to /v1/events on open.