Skip to content

Commit abe386a

Browse files
committed
Doc update
1 parent f89f094 commit abe386a

1 file changed

Lines changed: 380 additions & 0 deletions

File tree

Docs/RN_PushNotification.md

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
This guide explains how to implement AppsFlyer's push notification feature with deep linking in your React Native application.
2+
3+
## Overview
4+
5+
AppsFlyer's push notification feature enables you to:
6+
7+
- Measure push notification campaigns
8+
- Handle deep links from push notifications
9+
- Measure conversion attribution from push campaigns
10+
11+
**There are 2 methods of implementing push notification integration:**
12+
13+
1. **OneLink Method** - Uses OneLink URLs in the push payload
14+
2. **JSON Method** - Uses plain JSON structure in the push payload
15+
16+
Choose the method based on how your marketing team structures the push notifications.
17+
18+
## Prerequisites
19+
20+
- AppsFlyer React Native SDK installed and configured
21+
- A push notification provider (Firebase, OneSignal, etc.)
22+
- Basic AppsFlyer SDK implementation (init, start, attribution, deep linking)
23+
24+
## Method 1: OneLink Method
25+
26+
This method uses OneLink URLs embedded in the push notification payload.
27+
28+
### Required Parameters
29+
30+
The OneLink must contain at least these 3 parameters:
31+
32+
- `pid` - Media source identifier
33+
- `is_retargeting=true` - Indicates this is a re-engagement
34+
- `c` - Campaign name
35+
36+
### Push Payload Structure
37+
38+
```json
39+
{
40+
"data": {
41+
"message": "push message",
42+
"af_push_link": "https://yourapp.onelink.me/ABC123/campaign?pid=push_campaign&is_retargeting=true&c=holiday_sale"
43+
}
44+
}
45+
```
46+
47+
Or with nested structure:
48+
49+
```json
50+
{
51+
"data": {
52+
"message": "push message",
53+
"appsflyer": {
54+
"testing": {
55+
"link": "https://yourapp.onelink.me/ABC123/campaign?pid=push_campaign&is_retargeting=true&c=holiday_sale"
56+
}
57+
}
58+
}
59+
}
60+
```
61+
62+
### Implementation Steps
63+
64+
### 1. Set Up Listeners and Push Configuration
65+
66+
**Important:** Set up all listeners and push configuration BEFORE initializing the SDK:
67+
68+
```jsx
69+
import appsFlyer from 'react-native-appsflyer';
70+
71+
// 1. Handle conversions and attribution (BEFORE init)
72+
appsFlyer.onInstallConversionData((data) => {
73+
console.log('Install conversion data:', data);
74+
});
75+
76+
// 2. Handle deep links (BEFORE init)
77+
appsFlyer.onDeepLink((data) => {
78+
console.log('Deep link data:', data);
79+
});
80+
81+
// 3. Configure push notification deep link path (BEFORE init)
82+
// For simple structure: ["af_push_link"]
83+
// For nested structure: ["data", "appsflyer", "testing", "link"]
84+
appsFlyer.addPushNotificationDeepLinkPath(
85+
['af_push_link'], // Adjust based on your payload structure
86+
(success) => {
87+
console.log('Push notification path added successfully:', success);
88+
},
89+
(error) => {
90+
console.error('Error adding push notification path:', error);
91+
}
92+
);
93+
```
94+
95+
**Parameters for `addPushNotificationDeepLinkPath`:**
96+
97+
- `path`: Array of keys used to resolve the OneLink from push notification payload
98+
- `successCallback`: Called when the path is successfully added
99+
- `errorCallback`: Called if there's an error adding the path
100+
101+
### 2. Initialize and Start AppsFlyer SDK
102+
103+
After setting up all listeners and configurations, initialize and start the SDK:
104+
105+
```jsx
106+
// Initialize AppsFlyer (AFTER setting up listeners)
107+
appsFlyer.initSdk({
108+
devKey: 'YOUR_DEV_KEY',
109+
isDebug: true,
110+
appId: 'YOUR_APP_ID', // iOS only
111+
});
112+
113+
// Start AppsFlyer (AFTER init)
114+
appsFlyer.startSdk();
115+
```
116+
117+
**Parameters:**
118+
119+
- `path`: Array of keys used to resolve the deep link from push notification payload
120+
- `successCallback`: Called when the path is successfully added
121+
- `errorCallback`: Called if there's an error adding the path
122+
123+
### 3. Handle Push Notification Data
124+
125+
In your push notification provider callback (where you receive the notification payload), send the data to AppsFlyer:
126+
127+
```jsx
128+
// Example with Firebase messaging
129+
import messaging from '@react-native-firebase/messaging';
130+
131+
// Background/Quit state messages
132+
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
133+
console.log('Background message:', remoteMessage);
134+
135+
// Send push payload to AppsFlyer
136+
appsFlyer.sendPushNotificationData(
137+
remoteMessage.data, // The push notification payload
138+
(error) => {
139+
console.error('Error sending push data to AppsFlyer:', error);
140+
}
141+
);
142+
});
143+
144+
// Foreground messages
145+
messaging().onMessage(async (remoteMessage) => {
146+
console.log('Foreground message:', remoteMessage);
147+
148+
// Send push payload to AppsFlyer
149+
appsFlyer.sendPushNotificationData(
150+
remoteMessage.data,
151+
(error) => {
152+
console.error('Error sending push data to AppsFlyer:', error);
153+
}
154+
);
155+
});
156+
157+
// Handle notification opened from background/quit state
158+
messaging().onNotificationOpenedApp((remoteMessage) => {
159+
console.log('Notification opened:', remoteMessage);
160+
161+
// Send push payload to AppsFlyer
162+
appsFlyer.sendPushNotificationData(
163+
remoteMessage.data,
164+
(error) => {
165+
console.error('Error sending push data to AppsFlyer:', error);
166+
}
167+
);
168+
})
169+
```
170+
171+
## Method 2: JSON Method
172+
173+
This method uses a plain JSON structure in the push notification payload.
174+
175+
### Required Parameters
176+
177+
The `af` object must contain at least these 3 parameters:
178+
179+
- `pid` - Media source identifier
180+
- `is_retargeting: "true"` - Indicates this is a re-engagement (must be string "true")
181+
- `c` - Campaign name
182+
183+
### Push Payload Structure
184+
185+
The `af` object **must** be at the top level of the `data` object:
186+
187+
```json
188+
{
189+
"data": {
190+
"message": "push message",
191+
"af": {
192+
"pid": "push_campaign",
193+
"is_retargeting": "true",
194+
"c": "holiday_sale"
195+
}
196+
}
197+
}
198+
```
199+
200+
**❌ Invalid Structure (nested af object):**
201+
202+
```json
203+
{
204+
"data": {
205+
"message": "push message",
206+
"appsflyer_data": {
207+
"af": {
208+
"pid": "push_campaign",
209+
"is_retargeting": "true",
210+
"c": "holiday_sale"
211+
}
212+
}
213+
}
214+
}
215+
```
216+
217+
### Implementation Steps
218+
219+
For the JSON Legacy Method, you only need steps 1, 2, and 3 from the OneLink method above, but **skip the `addPushNotificationDeepLinkPath` call**:
220+
221+
```jsx
222+
// 1. Set up listeners (BEFORE init)
223+
appsFlyer.onInstallConversionData((data) => {
224+
console.log('Install conversion data:', data);
225+
});
226+
227+
appsFlyer.onDeepLink((data) => {
228+
console.log('Deep link data:', data);
229+
});
230+
231+
// 2. Initialize and start SDK
232+
appsFlyer.initSdk({
233+
devKey: 'YOUR_DEV_KEY',
234+
isDebug: true,
235+
appId: 'YOUR_APP_ID',
236+
});
237+
238+
appsFlyer.startSdk();
239+
240+
// 3. Handle push data the same way
241+
// The SDK will automatically detect the 'af' object in the payload
242+
```
243+
244+
## Complete Integration Examples
245+
246+
```jsx
247+
import React, { useEffect } from 'react';
248+
import appsFlyer from 'react-native-appsflyer';
249+
import messaging from '@react-native-firebase/messaging';
250+
251+
const AppsflyerPushIntegration = () => {
252+
useEffect(() => {
253+
// 1. Set up attribution and deep link handlers (BEFORE init)
254+
appsFlyer.onInstallConversionData((data) => {
255+
console.log('Conversion data:', data);
256+
});
257+
258+
appsFlyer.onDeepLink((data) => {
259+
console.log('Deep link:', data);
260+
});
261+
262+
// 2. Configure push notification deep link path (BEFORE init)
263+
appsFlyer.addPushNotificationDeepLinkPath(
264+
['af_push_link'], // Adjust based on your payload structure
265+
(success) => console.log('Push path configured'),
266+
(error) => console.error('Push path error:', error)
267+
);
268+
269+
// 3. Initialize AppsFlyer SDK (AFTER listeners and config)
270+
appsFlyer.initSdk({
271+
devKey: 'YOUR_DEV_KEY',
272+
isDebug: true,
273+
appId: 'YOUR_APP_ID',
274+
});
275+
276+
// 4. Start AppsFlyer (AFTER init)
277+
appsFlyer.startSdk();
278+
279+
// 5. Set up push notification handlers
280+
const handlePushData = (payload) => {
281+
appsFlyer.sendPushNotificationData(
282+
payload,
283+
(error) => console.error('Push data error:', error)
284+
);
285+
};
286+
287+
// Background messages
288+
messaging().setBackgroundMessageHandler(async (message) => {
289+
handlePushData(message.data);
290+
});
291+
292+
// Foreground messages
293+
const unsubscribe = messaging().onMessage(async (message) => {
294+
handlePushData(message.data);
295+
});
296+
297+
// Notification opened from background
298+
messaging().onNotificationOpenedApp((message) => {
299+
handlePushData(message.data);
300+
});
301+
302+
}, []);
303+
304+
return null; // This is just a setup component
305+
};
306+
307+
export default AppsflyerPushIntegration;
308+
```
309+
310+
## Important Notes
311+
312+
### Payload Processing
313+
314+
- **OneLink Method**: SDK processes the OneLink URL and extracts deep link data
315+
- **JSON Method**: SDK automatically appends `isPush: "true"` parameter to indicate the deep link came from push
316+
317+
## Debugging & Testing
318+
319+
### Expected Debug Logs
320+
321+
**OneLink Method:**
322+
323+
```
324+
UniversalLink/Deeplink found: https://yourapp.onelink.me/...
325+
```
326+
327+
**JSON Legacy Method:**
328+
329+
```
330+
Push Notification received af payload = {"c":"campaign_name", "is_retargeting":"true", "pid":"media_source"}
331+
```
332+
333+
### Session Payload Examples
334+
335+
**OneLink Method** - Look for:
336+
337+
```json
338+
{
339+
"af_deeplink": "https://yourapp.onelink.me/...",
340+
"meta": {
341+
"payloadKey": [["af_push_link"]]
342+
}
343+
}
344+
```
345+
346+
**JSON Legacy Method** - Look for:
347+
348+
```json
349+
{
350+
"af_deeplink": "{\"c\":\"campaign_name\",\"is_retargeting\":\"true\",\"pid\":\"media_source\",\"isPush\":\"true\"}"
351+
}
352+
```
353+
354+
## Troubleshooting
355+
356+
### Common Issues
357+
358+
**OneLink Method:**
359+
360+
- **Deep links not working**: Verify the key path in `addPushNotificationDeepLinkPath` matches your payload structure
361+
- **OneLink not detected**: Ensure the OneLink contains required parameters (pid, is_retargeting=true, c)
362+
- **Payload not processed**: Check that `addPushNotificationDeepLinkPath` is called before `initSdk`
363+
364+
**JSON Method:**
365+
366+
- **Re-engagement not recorded**: Verify the `af` object is at the top level of `data`, not nested
367+
- **Missing parameters**: Ensure `pid`, `is_retargeting: "true"`, and `c` are all present
368+
- **Wrong data types**: `is_retargeting` must be string "true", not boolean
369+
370+
**General Issues:**
371+
372+
- **Android crashes**: Verify app activity is available when calling `sendPushNotificationData`
373+
- **Listeners not firing**: Ensure all listeners are set up before calling `initSdk` and `startSdk`
374+
- **Duplicate processing**: SDK prevents duplicate processing of the same payload in the same cold launch
375+
376+
## Resources
377+
378+
- [AppsFlyer Push Notification Campaigns](https://support.appsflyer.com/hc/en-us/articles/207034486)
379+
- [React Native SDK Documentation](https://dev.appsflyer.com/hc/docs/react-native-plugin)
380+
- [Deep Link Integration Guide](https://dev.appsflyer.com/hc/docs/react-native-plugin#deep-linking)

0 commit comments

Comments
 (0)