支持推送通知
通过将 Firebase Cloud Messaging (FCM) 与 Singular SDK 集成,跟踪用户与推送通知的互动,以衡量再参与活动并准确归因于转化。
请遵循以下实施指南,以确保通知数据正确传递到 Singular SDK,从而获得正确的归因。
为什么要跟踪推送通知?推送通知能推动用户重新参与,但跟踪需要正确的整合。Singular 可确保与通知互动的用户得到正确归因,从而优化营销活动和参与策略。
实施指南
集成 Singular SDK
使用Singular React Native SDK 指南中的标准安装说明,在React Native 项目中集成Singular SDK。
设置 Firebase 云消息服务
安装 Firebase 软件包并配置特定于平台的设置,以支持推送通知。
安装 Firebase 软件包
为核心功能和消息支持添加 React Native Firebase 依赖项。
npm install @react-native-firebase/app
npm install @react-native-firebase/messaging
iOS 配置
在 Firebase 中注册 iOS 应用程序,并在 Xcode 中配置推送通知功能。
- 注册 iOS 应用程序:在 Firebase 控制台项目中创建 iOS 应用程序
-
添加配置文件:下载
GoogleService-Info.plist并将其添加到您的 Xcode 项目中 - 启用功能:在 Xcode 项目设置中,启用推送通知功能
- 启用后台模式:启用后台模式并勾选远程通知
安卓配置
在 Firebase 中注册您的 Android 应用程序,并将配置文件添加到您的项目中。
- 注册 Android 应用程序:在 Firebase 控制台项目中创建一个 Android 应用程序
-
添加配置文件:下载
google-services.json并将其放入android/app/ - 验证依赖关系:确保已添加 Firebase 消息传递依赖项并授予权限
配置推送链接路径
定义推送通知有效载荷结构中 Singular 跟踪链接所在的 JSON 路径。
通过传递字符串数组配置推送链接路径,字符串数组指定了通知数据结构中 Singular 链接的关键路径。每个路径都是一个数组,代表键的嵌套结构。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';
const config: SingularConfig = {
apikey: 'YOUR_SDK_KEY',
secret: 'YOUR_SDK_SECRET',
pushNotificationsLinkPaths: [
['sng_link'], // Top-level key
['path', 'to', 'url'], // Nested path
['rootObj', 'nestedObj', 'singularLink'] // Deep nested path
]
};
NativeSingular.init(config);
import { Singular, SingularConfig } from 'singular-react-native';
const config = new SingularConfig(
'YOUR_SDK_KEY',
'YOUR_SDK_SECRET'
)
.withPushNotificationsLinkPaths([
['sng_link'], // Top-level key
['path', 'to', 'url'], // Nested path
['rootObj', 'nestedObj', 'singularLink'] // Deep nested path
]);
Singular.init(config);
路径配置示例:
-
简单键:对有效载荷中的顶级键使用
['sng_link'] -
嵌套键:使用
['rootObj', 'nestedObj', 'key']遍历嵌套的 JSON 结构 - 多路径:定义多个路径数组,以检查奇异链接的不同可能位置
有关完整的方法文档,请参阅withPushNotificationsLinkPaths 参考资料。
特定平台处理
iOS 推送通知处理
处于终止状态的应用程序
配置 iOS AppDelegate,将启动选项传递给 Singular SDK,以便在应用程序从终止状态打开时进行自动推送跟踪。
在AppDelegate 中,在didFinishLaunchingWithOptions 内添加以下内容:
// Import at the top of the file
import Singular
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = RCTReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
window = UIWindow(frame: UIScreen.main.bounds)
if let singularBridge = NSClassFromString("SingularBridge") {
let selector = NSSelectorFromString("startSessionWithLaunchOptions:")
if singularBridge.responds(to: selector) {
singularBridge.perform(selector, with: launchOptions, afterDelay: 1)
}
}
factory.startReactNative(
withModuleName: "YourAppName", // Update with your App Name
in: window,
launchOptions: launchOptions
)
return true
}
// Import at the top of the file
#import <Singular-React-Native/SingularBridge.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Pass launch options to Singular for push tracking
[SingularBridge startSessionWithLaunchOptions:launchOptions];
// Your other initialization code
return YES;
}
自动处理:当用户在应用程序未运行时点击推送通知时,Singular 会在应用程序启动时通过启动选项自动捕获通知有效载荷。
后台或前台应用程序
当应用程序在后台或前台状态下接收通知时,使用handlePushNotification() 方法将推送数据传递给 SDK。
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/jsNativeSingular';
import messaging from '@react-native-firebase/messaging';
export default function App() {
useEffect(() => {
// Handle foreground messages
const unsubscribeBackground = messaging().onMessage(handleForegroundMessage);
// Handle messages that opened the app from background
messaging().onNotificationOpenedApp(handleBackgroundMessage);
return () => {
unsubscribeBackground();
};
}, []);
function handleForegroundMessage(remoteMessage) {
console.log('Foreground message received:', remoteMessage);
// Pass notification data to Singular
if (remoteMessage.data) {
NativeSingular.handlePushNotification(remoteMessage.data);
}
// Your custom notification handling
displayLocalNotification(remoteMessage);
}
function handleBackgroundMessage(remoteMessage) {
console.log('Background message opened app:', remoteMessage);
// Pass notification data to Singular
if (remoteMessage.data) {
NativeSingular.handlePushNotification(remoteMessage.data);
}
// Navigate to appropriate screen
navigateFromNotification(remoteMessage);
}
function displayLocalNotification(remoteMessage) {
// Your notification display logic
console.log('Displaying notification:', remoteMessage.notification?.title);
}
function navigateFromNotification(remoteMessage) {
// Your navigation logic based on notification data
const route = remoteMessage.data?.route;
console.log('Navigating to:', route);
}
return (
// Your app components
null
);
}
import React, { useEffect } from 'react';
import { Singular } from 'singular-react-native';
import messaging from '@react-native-firebase/messaging';
export default function App() {
useEffect(() => {
// Handle background messages
const unsubscribeBackground = messaging().onMessage(handleForegroundMessage);
// Handle messages that opened the app from background
messaging().onNotificationOpenedApp(handleBackgroundMessage);
return () => {
unsubscribeBackground();
};
}, []);
function handleForegroundMessage(remoteMessage) {
console.log('Foreground message received:', remoteMessage);
// Pass notification data to Singular
if (remoteMessage.data) {
Singular.handlePushNotification(remoteMessage.data);
}
// Your custom notification handling
displayLocalNotification(remoteMessage);
}
function handleBackgroundMessage(remoteMessage) {
console.log('Background message opened app:', remoteMessage);
// Pass notification data to Singular
if (remoteMessage.data) {
Singular.handlePushNotification(remoteMessage.data);
}
// Navigate to appropriate screen
navigateFromNotification(remoteMessage);
}
function displayLocalNotification(remoteMessage) {
// Your notification display logic
console.log('Displaying notification:', remoteMessage.notification?.title);
}
function navigateFromNotification(remoteMessage) {
// Your navigation logic based on notification data
const route = remoteMessage.data?.route;
console.log('Navigating to:', route);
}
return (
// Your app components
);
}
有关完整的方法文档,请参阅handlePushNotification 参考资料。
安卓推送通知处理
处于终止状态的应用程序
处于终止状态的 Android 应用程序无需任何操作。当用户点击通知时,React Native 桥接层会自动处理这种情况。
自动处理:当用户在应用程序未运行时点击推送通知时,Singular 会通过原生桥接集成自动捕获通知数据。
后台或前台应用程序
配置您的 Android MainActivity,以便在应用程序处于后台或前台状态时将通知意图传递给 Singular SDK。
在您的 MainActivity(例如MainActivity.java 或MainActivity.kt )中,覆盖onNewIntent :
// Add imports at the top
import android.content.Intent;
import net.singular.react_native.SingularBridgeModule;
// Add to MainActivity class
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// Pass intent to Singular for push tracking
SingularBridgeModule.onNewIntent(intent);
}
// Add imports at the top
import android.content.Intent
import net.singular.react_native.SingularBridgeModule
// Add to MainActivity class
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// Pass intent to Singular for push tracking
SingularBridgeModule.onNewIntent(intent)
}
此外,在 React Native 代码中使用与上述 iOS 背景/前台处理相同的方法实现 Firebase 消息处理。
验证指南
验证启动会话中的有效负载
通过检查启动会话 API 调用,确认推送通知链接已正确传递给 Singular。
当用户点击通知时,Singular SDK 会在开始会话请求的singular_link 参数下包含推送通知有效载荷。
启动会话请求示例:
https://sdk-api-v1.singular.net/api/v1/start?
a=<SDK-Key>
&singular_link=https://singularassist2.sng.link/C4nw9/r1m0?_dl=singular%3A%2F%2Ftest&_smtype=3
&i=net.singular.sampleapp
&s=1740905574084
&sdk=Singular/React-Native-v1.0.0
替代验证:使用 Singular SDK 控制台验证推送通知跟踪。检查Deeplink URL字段,确认跟踪链接已正确捕获。
高级配置
ESP 域配置
如果您在电子邮件服务提供商(ESP)或其他第三方域中封装 Singular 链接,请配置外部域。
// TurboModule direct API (React Native 0.76+ New Architecture)
import NativeSingular from 'singular-react-native/jsNativeSingular';
// Configure ESP domains for wrapped Singular links
const config: SingularConfig = {
apikey: 'YOUR_SDK_KEY',
secret: 'YOUR_SDK_SECRET',
espDomains: ['sl.esp.link', 'custom.domain.com']
};
NativeSingular.init(config);
import { Singular, SingularConfig } from 'singular-react-native';
// Configure ESP domains for wrapped Singular links
const config = new SingularConfig(
'YOUR_SDK_KEY',
'YOUR_SDK_SECRET'
)
.withESPDomains(['sl.esp.link', 'custom.domain.com']);
Singular.init(config);
安全提示:默认情况下,只允许使用 "Singular 管理链接 "页面中预定义的sng.link域。 如果使用封装链接,请明确配置 ESP 域。
有关完整的方法文档,请参阅withESPDomains 参考资料。
动态深度链接路由
通过配置一个具有动态重定向重写功能的 Singular 跟踪链接,在单个通知中实现多个深度链接目的地。
用例示例:具有多个操作选项的突发新闻通知
-
阅读最新新闻:
newsapp://article?id=12345 -
热门话题
newsapp://trending -
体育:
newsapp://sports
与其创建多个跟踪链接,不如使用一个单一链接,并根据用户选择动态覆盖重定向。有关实施详情,请参阅在奇异跟踪链接中覆盖重定向。
重要注意事项
实施注意事项
-
无回调处理程序:与
withSingularLink不同,推送通知功能不提供有效载荷回调。请实施您自己的深度链接逻辑,将用户引导至您应用中的特定内容。 - 归属流:当用户点击通知时,Singular 会检索有效载荷,并将其包含在 SDK 初始化触发的启动会话事件中。后台会处理这些数据,对推送通知接触点进行归因,并注册重新参与跟踪。
-
域限制:默认情况下,只允许使用 "管理链接 "页面上的单链接域 (
sng.link)。请使用withESPDomains()为封装链接明确配置 ESP 域。 - 平台差异:iOS 需要 AppDelegate 对终止状态进行配置,而 Android 则通过桥接模块自动进行处理
成功:通过这些步骤,您的应用程序现在可以通过 Singular 跟踪推送通知互动,从而提高活动性能洞察力,确保准确的再参与归因。