@datalyr/react-native 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +3 -131
- package/android/build.gradle +0 -7
- package/android/src/main/java/com/datalyr/reactnative/DatalyrNativeModule.java +2 -380
- package/android/src/main/java/com/datalyr/reactnative/DatalyrPackage.java +1 -1
- package/datalyr-react-native.podspec +3 -7
- package/expo-module.config.json +4 -1
- package/ios/DatalyrNativeModule.swift +0 -266
- package/lib/datalyr-sdk.d.ts +1 -4
- package/lib/datalyr-sdk.js +7 -143
- package/lib/http-client.js +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/integrations/index.d.ts +3 -4
- package/lib/integrations/index.js +3 -4
- package/lib/native/DatalyrNativeBridge.d.ts +6 -22
- package/lib/native/DatalyrNativeBridge.js +6 -147
- package/lib/native/index.d.ts +1 -1
- package/lib/native/index.js +1 -1
- package/lib/types.d.ts +1 -19
- package/package.json +3 -5
- package/src/datalyr-sdk-expo.ts +6 -141
- package/src/datalyr-sdk.ts +8 -173
- package/src/http-client.ts +2 -2
- package/src/index.ts +1 -1
- package/src/integrations/index.ts +3 -4
- package/src/native/DatalyrNativeBridge.ts +6 -241
- package/src/native/index.ts +0 -2
- package/src/types.ts +2 -25
- package/src/utils-expo.ts +2 -2
- package/ios/DatalyrObjCExceptionCatcher.h +0 -14
- package/ios/DatalyrObjCExceptionCatcher.m +0 -30
- package/lib/integrations/meta-integration.d.ts +0 -77
- package/lib/integrations/meta-integration.js +0 -219
- package/lib/integrations/tiktok-integration.d.ts +0 -83
- package/lib/integrations/tiktok-integration.js +0 -360
- package/src/integrations/meta-integration.ts +0 -239
- package/src/integrations/tiktok-integration.ts +0 -363
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,45 @@ All notable changes to the Datalyr React Native SDK will be documented in this f
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.6.0] - 2026-03
|
|
9
|
+
|
|
10
|
+
### Removed
|
|
11
|
+
- **Meta (Facebook) SDK** - Removed FBSDKCoreKit (iOS) and facebook-android-sdk (Android) dependencies
|
|
12
|
+
- **TikTok Business SDK** - Removed TikTokBusinessSDK (iOS) and tiktok-business-android-sdk (Android) dependencies
|
|
13
|
+
- Removed ByteDance maven repository from Android build
|
|
14
|
+
- Removed `MetaConfig`, `TikTokConfig` TypeScript interfaces
|
|
15
|
+
- Removed `MetaNativeBridge`, `TikTokNativeBridge` native bridge modules
|
|
16
|
+
- Removed all client-side event forwarding to Meta/TikTok
|
|
17
|
+
- Removed `meta-integration.ts`, `tiktok-integration.ts`, `DatalyrObjCExceptionCatcher`
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- Conversion event routing to Meta (CAPI), TikTok (Events API), and Google Ads is now handled entirely server-side via the Datalyr postback system
|
|
21
|
+
- IDFA/ATT and GAID now use native Apple/Google frameworks directly
|
|
22
|
+
- `getPlatformIntegrationStatus()` returns only `appleSearchAds` and `playInstallReferrer`
|
|
23
|
+
|
|
24
|
+
### Migration from v1.5.x
|
|
25
|
+
Remove `meta` and `tiktok` config objects from your `initialize()` call:
|
|
26
|
+
```typescript
|
|
27
|
+
// Before (v1.5.x)
|
|
28
|
+
await Datalyr.initialize({
|
|
29
|
+
apiKey: 'dk_...',
|
|
30
|
+
meta: { appId: 'FB_APP_ID', clientToken: '...' }, // REMOVE
|
|
31
|
+
tiktok: { appId: '...', tiktokAppId: '...' }, // REMOVE
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// After (v1.6.0)
|
|
35
|
+
await Datalyr.initialize({
|
|
36
|
+
apiKey: 'dk_...',
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
No other code changes needed. All tracking methods (`trackPurchase`, `trackAddToCart`, etc.) work the same — events are routed to ad platforms server-side via your Datalyr postback rules.
|
|
40
|
+
|
|
41
|
+
If you were importing `metaIntegration` or `tiktokIntegration` directly, remove those imports — they no longer exist.
|
|
42
|
+
|
|
43
|
+
iOS: Remove from Info.plist: `FacebookAppID`, `FacebookClientToken`, `FacebookDisplayName`, and `LSApplicationQueriesSchemes` entries for TikTok.
|
|
44
|
+
|
|
45
|
+
Android: No changes needed — Meta/TikTok dependencies are automatically removed on `pod install` / gradle sync.
|
|
46
|
+
|
|
8
47
|
## [1.3.1] - 2026-01
|
|
9
48
|
|
|
10
49
|
### Added
|
package/README.md
CHANGED
|
@@ -18,14 +18,11 @@ Mobile analytics and attribution SDK for React Native and Expo. Track events, id
|
|
|
18
18
|
- [User Properties](#user-properties)
|
|
19
19
|
- [Attribution](#attribution)
|
|
20
20
|
- [Automatic Capture](#automatic-capture)
|
|
21
|
-
- [Deferred Deep Links](#deferred-deep-links)
|
|
22
21
|
- [Web-to-App Attribution](#web-to-app-attribution)
|
|
23
22
|
- [Event Queue](#event-queue)
|
|
24
23
|
- [Auto Events](#auto-events)
|
|
25
24
|
- [SKAdNetwork](#skadnetwork)
|
|
26
25
|
- [Platform Integrations](#platform-integrations)
|
|
27
|
-
- [Meta](#meta-facebook)
|
|
28
|
-
- [TikTok](#tiktok)
|
|
29
26
|
- [Apple Search Ads](#apple-search-ads)
|
|
30
27
|
- [Expo Support](#expo-support)
|
|
31
28
|
- [TypeScript](#typescript)
|
|
@@ -46,38 +43,6 @@ npm install @datalyr/react-native
|
|
|
46
43
|
cd ios && pod install
|
|
47
44
|
```
|
|
48
45
|
|
|
49
|
-
This installs the SDK with bundled Meta and TikTok native SDKs.
|
|
50
|
-
|
|
51
|
-
Add to `ios/YourApp/Info.plist`:
|
|
52
|
-
|
|
53
|
-
```xml
|
|
54
|
-
<!-- Meta SDK -->
|
|
55
|
-
<key>FacebookAppID</key>
|
|
56
|
-
<string>YOUR_FACEBOOK_APP_ID</string>
|
|
57
|
-
<key>FacebookClientToken</key>
|
|
58
|
-
<string>YOUR_CLIENT_TOKEN</string>
|
|
59
|
-
<key>FacebookDisplayName</key>
|
|
60
|
-
<string>Your App Name</string>
|
|
61
|
-
|
|
62
|
-
<key>CFBundleURLTypes</key>
|
|
63
|
-
<array>
|
|
64
|
-
<dict>
|
|
65
|
-
<key>CFBundleURLSchemes</key>
|
|
66
|
-
<array>
|
|
67
|
-
<string>fbYOUR_FACEBOOK_APP_ID</string>
|
|
68
|
-
</array>
|
|
69
|
-
</dict>
|
|
70
|
-
</array>
|
|
71
|
-
|
|
72
|
-
<!-- TikTok SDK -->
|
|
73
|
-
<key>LSApplicationQueriesSchemes</key>
|
|
74
|
-
<array>
|
|
75
|
-
<string>tiktok</string>
|
|
76
|
-
<string>snssdk1180</string>
|
|
77
|
-
<string>snssdk1233</string>
|
|
78
|
-
</array>
|
|
79
|
-
```
|
|
80
|
-
|
|
81
46
|
### Android Setup
|
|
82
47
|
|
|
83
48
|
No additional setup required.
|
|
@@ -171,9 +136,6 @@ await Datalyr.initialize({
|
|
|
171
136
|
// iOS
|
|
172
137
|
skadTemplate?: 'ecommerce' | 'gaming' | 'subscription',
|
|
173
138
|
|
|
174
|
-
// Platform SDKs
|
|
175
|
-
meta?: MetaConfig,
|
|
176
|
-
tiktok?: TikTokConfig,
|
|
177
139
|
});
|
|
178
140
|
```
|
|
179
141
|
|
|
@@ -221,7 +183,7 @@ await Datalyr.screen('Product Details', {
|
|
|
221
183
|
|
|
222
184
|
### E-Commerce Events
|
|
223
185
|
|
|
224
|
-
Standard e-commerce events
|
|
186
|
+
Standard e-commerce events:
|
|
225
187
|
|
|
226
188
|
```typescript
|
|
227
189
|
// View product
|
|
@@ -283,7 +245,6 @@ await Datalyr.identify('user_123', {
|
|
|
283
245
|
After `identify()`:
|
|
284
246
|
- All future events include `user_id`
|
|
285
247
|
- Historical anonymous events can be linked server-side
|
|
286
|
-
- User data is forwarded to Meta/TikTok for Advanced Matching
|
|
287
248
|
|
|
288
249
|
### User Properties
|
|
289
250
|
|
|
@@ -336,27 +297,6 @@ Captured parameters:
|
|
|
336
297
|
| Click IDs | `fbclid`, `gclid`, `ttclid`, `twclid`, `li_click_id`, `msclkid` |
|
|
337
298
|
| Campaign | `campaign_id`, `adset_id`, `ad_id` |
|
|
338
299
|
|
|
339
|
-
### Deferred Deep Links
|
|
340
|
-
|
|
341
|
-
Capture attribution from App Store installs (iOS):
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
await Datalyr.initialize({
|
|
345
|
-
apiKey: 'dk_your_api_key',
|
|
346
|
-
meta: {
|
|
347
|
-
appId: '1234567890',
|
|
348
|
-
enableDeferredDeepLink: true,
|
|
349
|
-
},
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// Check for deferred attribution
|
|
353
|
-
const deferred = Datalyr.getDeferredAttributionData();
|
|
354
|
-
if (deferred) {
|
|
355
|
-
console.log(deferred.fbclid); // Facebook click ID
|
|
356
|
-
console.log(deferred.campaignId); // Campaign ID
|
|
357
|
-
}
|
|
358
|
-
```
|
|
359
|
-
|
|
360
300
|
### Web-to-App Attribution
|
|
361
301
|
|
|
362
302
|
Automatically recover attribution from a web prelander when users install the app from an ad.
|
|
@@ -474,46 +414,7 @@ await Datalyr.trackPurchase(99.99, 'USD');
|
|
|
474
414
|
|
|
475
415
|
## Platform Integrations
|
|
476
416
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
### Meta (Facebook)
|
|
480
|
-
|
|
481
|
-
```typescript
|
|
482
|
-
await Datalyr.initialize({
|
|
483
|
-
apiKey: 'dk_your_api_key',
|
|
484
|
-
meta: {
|
|
485
|
-
appId: '1234567890',
|
|
486
|
-
clientToken: 'abc123',
|
|
487
|
-
enableDeferredDeepLink: true,
|
|
488
|
-
enableAppEvents: true,
|
|
489
|
-
},
|
|
490
|
-
});
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### TikTok
|
|
494
|
-
|
|
495
|
-
```typescript
|
|
496
|
-
await Datalyr.initialize({
|
|
497
|
-
apiKey: 'dk_your_api_key',
|
|
498
|
-
tiktok: {
|
|
499
|
-
appId: 'your_app_id', // Events API App ID
|
|
500
|
-
tiktokAppId: '7123456789', // TikTok App ID (Developer Portal)
|
|
501
|
-
accessToken: 'your_access_token', // Events API Access Token
|
|
502
|
-
enableAppEvents: true,
|
|
503
|
-
},
|
|
504
|
-
});
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
**Where to find your TikTok credentials:**
|
|
508
|
-
|
|
509
|
-
| Credential | Where to get it |
|
|
510
|
-
|------------|----------------|
|
|
511
|
-
| `tiktokAppId` | [TikTok Developer Portal](https://developers.tiktok.com) → Your App → App ID |
|
|
512
|
-
| `appId` | TikTok Business Center → Assets → Events → Your App → App ID |
|
|
513
|
-
| `accessToken` | TikTok Business Center → Assets → Events → Your App → Settings → Access Token |
|
|
514
|
-
|
|
515
|
-
> **Note:** The `accessToken` enables client-side TikTok SDK features (enhanced attribution, real-time event forwarding). Without it, events are still tracked server-side via Datalyr postbacks — you'll see a warning in debug mode.
|
|
516
|
-
```
|
|
417
|
+
Conversion event routing to Meta, TikTok, and Google is handled server-side via the postback system. No client-side SDK configuration is needed for these platforms.
|
|
517
418
|
|
|
518
419
|
### Apple Search Ads
|
|
519
420
|
|
|
@@ -554,7 +455,7 @@ await Datalyr.updateTrackingAuthorization(status === 'granted');
|
|
|
554
455
|
|
|
555
456
|
```typescript
|
|
556
457
|
const status = Datalyr.getPlatformIntegrationStatus();
|
|
557
|
-
// {
|
|
458
|
+
// { appleSearchAds: true }
|
|
558
459
|
```
|
|
559
460
|
|
|
560
461
|
---
|
|
@@ -683,35 +584,6 @@ cd android && ./gradlew clean
|
|
|
683
584
|
npx react-native run-android
|
|
684
585
|
```
|
|
685
586
|
|
|
686
|
-
### Meta SDK Not Working
|
|
687
|
-
|
|
688
|
-
Verify Info.plist:
|
|
689
|
-
```xml
|
|
690
|
-
<key>FacebookAppID</key>
|
|
691
|
-
<string>YOUR_APP_ID</string>
|
|
692
|
-
<key>FacebookClientToken</key>
|
|
693
|
-
<string>YOUR_CLIENT_TOKEN</string>
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
Check status: `Datalyr.getPlatformIntegrationStatus()`
|
|
697
|
-
|
|
698
|
-
### TikTok SDK Not Working
|
|
699
|
-
|
|
700
|
-
1. Make sure you have all three TikTok credentials (see [TikTok setup](#tiktok))
|
|
701
|
-
2. The `accessToken` is required for client-side SDK — without it, you'll see a warning but server-side tracking still works
|
|
702
|
-
3. Check status: `Datalyr.getPlatformIntegrationStatus()`
|
|
703
|
-
|
|
704
|
-
```typescript
|
|
705
|
-
await Datalyr.initialize({
|
|
706
|
-
apiKey: 'dk_your_api_key',
|
|
707
|
-
tiktok: {
|
|
708
|
-
appId: 'your_app_id',
|
|
709
|
-
tiktokAppId: '7123456789012345',
|
|
710
|
-
accessToken: 'your_access_token',
|
|
711
|
-
},
|
|
712
|
-
});
|
|
713
|
-
```
|
|
714
|
-
|
|
715
587
|
### SKAdNetwork Not Updating
|
|
716
588
|
|
|
717
589
|
1. iOS 14.0+ required (16.1+ for SKAN 4.0)
|
package/android/build.gradle
CHANGED
|
@@ -36,19 +36,12 @@ android {
|
|
|
36
36
|
repositories {
|
|
37
37
|
google()
|
|
38
38
|
mavenCentral()
|
|
39
|
-
maven { url "https://artifact.bytedance.com/repository/pangle" } // TikTok SDK
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
dependencies {
|
|
43
42
|
// React Native
|
|
44
43
|
implementation "com.facebook.react:react-native:+"
|
|
45
44
|
|
|
46
|
-
// Meta (Facebook) SDK - Updated Jan 2026
|
|
47
|
-
implementation 'com.facebook.android:facebook-android-sdk:18.1.3'
|
|
48
|
-
|
|
49
|
-
// TikTok Business SDK - Updated Jan 2026
|
|
50
|
-
implementation 'com.tiktok.business.sdk:tiktok-business-android-sdk:1.6.0'
|
|
51
|
-
|
|
52
45
|
// Google Play Install Referrer
|
|
53
46
|
implementation 'com.android.installreferrer:installreferrer:2.2'
|
|
54
47
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
package com.datalyr.reactnative;
|
|
2
2
|
|
|
3
|
-
import android.os.Bundle;
|
|
4
3
|
import android.util.Log;
|
|
5
4
|
|
|
6
5
|
import com.facebook.react.bridge.Arguments;
|
|
@@ -8,44 +7,21 @@ import com.facebook.react.bridge.Promise;
|
|
|
8
7
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
9
8
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
10
9
|
import com.facebook.react.bridge.ReactMethod;
|
|
11
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
12
|
-
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|
13
10
|
import com.facebook.react.bridge.WritableMap;
|
|
14
11
|
|
|
15
|
-
// Meta (Facebook) SDK imports
|
|
16
|
-
import com.facebook.FacebookSdk;
|
|
17
|
-
import com.facebook.appevents.AppEventsLogger;
|
|
18
|
-
import com.facebook.appevents.AppEventsConstants;
|
|
19
|
-
import com.facebook.appevents.UserDataStore;
|
|
20
|
-
import com.facebook.bolts.AppLinks;
|
|
21
|
-
import android.net.Uri;
|
|
22
|
-
|
|
23
|
-
// TikTok SDK imports
|
|
24
|
-
import com.tiktok.TikTokBusinessSdk;
|
|
25
|
-
import com.tiktok.TikTokBusinessSdk.TTConfig;
|
|
26
|
-
import com.tiktok.appevents.TikTokAppEvent;
|
|
27
|
-
import com.tiktok.appevents.TikTokAppEventLogger;
|
|
28
|
-
|
|
29
12
|
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
|
|
30
13
|
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
|
|
31
14
|
|
|
32
|
-
import java.math.BigDecimal;
|
|
33
|
-
import java.util.Currency;
|
|
34
|
-
import java.util.HashMap;
|
|
35
|
-
import java.util.Map;
|
|
36
|
-
|
|
37
15
|
/**
|
|
38
16
|
* Datalyr Native Module for Android
|
|
39
|
-
* Provides
|
|
17
|
+
* Provides advertiser info (GAID) for React Native.
|
|
18
|
+
* Conversion event routing to ad platforms is handled server-side via postback.
|
|
40
19
|
*/
|
|
41
20
|
public class DatalyrNativeModule extends ReactContextBaseJavaModule {
|
|
42
21
|
private static final String TAG = "DatalyrNative";
|
|
43
22
|
private static final String MODULE_NAME = "DatalyrNative";
|
|
44
23
|
|
|
45
24
|
private final ReactApplicationContext reactContext;
|
|
46
|
-
private AppEventsLogger metaLogger;
|
|
47
|
-
private boolean metaInitialized = false;
|
|
48
|
-
private boolean tiktokInitialized = false;
|
|
49
25
|
|
|
50
26
|
public DatalyrNativeModule(ReactApplicationContext context) {
|
|
51
27
|
super(context);
|
|
@@ -57,328 +33,6 @@ public class DatalyrNativeModule extends ReactContextBaseJavaModule {
|
|
|
57
33
|
return MODULE_NAME;
|
|
58
34
|
}
|
|
59
35
|
|
|
60
|
-
// ============================================================================
|
|
61
|
-
// Meta (Facebook) SDK Methods
|
|
62
|
-
// ============================================================================
|
|
63
|
-
|
|
64
|
-
@ReactMethod
|
|
65
|
-
public void initializeMetaSDK(String appId, String clientToken, boolean advertiserTrackingEnabled, Promise promise) {
|
|
66
|
-
try {
|
|
67
|
-
// Initialize Facebook SDK
|
|
68
|
-
FacebookSdk.setApplicationId(appId);
|
|
69
|
-
if (clientToken != null && !clientToken.isEmpty()) {
|
|
70
|
-
FacebookSdk.setClientToken(clientToken);
|
|
71
|
-
}
|
|
72
|
-
FacebookSdk.setAdvertiserIDCollectionEnabled(advertiserTrackingEnabled);
|
|
73
|
-
FacebookSdk.setAutoLogAppEventsEnabled(true);
|
|
74
|
-
FacebookSdk.sdkInitialize(reactContext.getApplicationContext());
|
|
75
|
-
|
|
76
|
-
// Create logger instance
|
|
77
|
-
metaLogger = AppEventsLogger.newLogger(reactContext.getApplicationContext());
|
|
78
|
-
metaInitialized = true;
|
|
79
|
-
|
|
80
|
-
Log.d(TAG, "Meta SDK initialized with App ID: " + appId);
|
|
81
|
-
promise.resolve(true);
|
|
82
|
-
} catch (Exception e) {
|
|
83
|
-
Log.e(TAG, "Failed to initialize Meta SDK", e);
|
|
84
|
-
promise.reject("meta_init_error", "Failed to initialize Meta SDK: " + e.getMessage());
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@ReactMethod
|
|
89
|
-
public void fetchDeferredAppLink(Promise promise) {
|
|
90
|
-
if (!metaInitialized) {
|
|
91
|
-
promise.resolve(null);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
AppLinks.getTargetUrlFromInboundIntent(reactContext.getApplicationContext(), reactContext.getCurrentActivity().getIntent())
|
|
97
|
-
.continueWith(task -> {
|
|
98
|
-
if (task.getError() != null) {
|
|
99
|
-
Log.d(TAG, "Deferred app link error: " + task.getError().getMessage());
|
|
100
|
-
promise.resolve(null);
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
Uri targetUrl = task.getResult();
|
|
105
|
-
if (targetUrl != null) {
|
|
106
|
-
promise.resolve(targetUrl.toString());
|
|
107
|
-
} else {
|
|
108
|
-
promise.resolve(null);
|
|
109
|
-
}
|
|
110
|
-
return null;
|
|
111
|
-
});
|
|
112
|
-
} catch (Exception e) {
|
|
113
|
-
Log.d(TAG, "Deferred app link not available");
|
|
114
|
-
promise.resolve(null);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
@ReactMethod
|
|
119
|
-
public void logMetaEvent(String eventName, Double valueToSum, ReadableMap parameters, Promise promise) {
|
|
120
|
-
if (!metaInitialized || metaLogger == null) {
|
|
121
|
-
promise.resolve(false);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
Bundle params = readableMapToBundle(parameters);
|
|
127
|
-
|
|
128
|
-
if (valueToSum != null) {
|
|
129
|
-
metaLogger.logEvent(eventName, valueToSum, params);
|
|
130
|
-
} else if (params.isEmpty()) {
|
|
131
|
-
metaLogger.logEvent(eventName);
|
|
132
|
-
} else {
|
|
133
|
-
metaLogger.logEvent(eventName, params);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
Log.d(TAG, "Meta event logged: " + eventName);
|
|
137
|
-
promise.resolve(true);
|
|
138
|
-
} catch (Exception e) {
|
|
139
|
-
Log.e(TAG, "Failed to log Meta event", e);
|
|
140
|
-
promise.reject("meta_event_error", "Failed to log Meta event: " + e.getMessage());
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@ReactMethod
|
|
145
|
-
public void logMetaPurchase(double amount, String currency, ReadableMap parameters, Promise promise) {
|
|
146
|
-
if (!metaInitialized || metaLogger == null) {
|
|
147
|
-
promise.resolve(false);
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
Bundle params = readableMapToBundle(parameters);
|
|
153
|
-
BigDecimal purchaseAmount = BigDecimal.valueOf(amount);
|
|
154
|
-
Currency currencyObj = Currency.getInstance(currency);
|
|
155
|
-
|
|
156
|
-
metaLogger.logPurchase(purchaseAmount, currencyObj, params);
|
|
157
|
-
|
|
158
|
-
Log.d(TAG, "Meta purchase logged: " + amount + " " + currency);
|
|
159
|
-
promise.resolve(true);
|
|
160
|
-
} catch (Exception e) {
|
|
161
|
-
Log.e(TAG, "Failed to log Meta purchase", e);
|
|
162
|
-
promise.reject("meta_purchase_error", "Failed to log Meta purchase: " + e.getMessage());
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
@ReactMethod
|
|
167
|
-
public void setMetaUserData(ReadableMap userData, Promise promise) {
|
|
168
|
-
if (!metaInitialized) {
|
|
169
|
-
promise.resolve(false);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
try {
|
|
174
|
-
// Set user data for Advanced Matching
|
|
175
|
-
Bundle userDataBundle = new Bundle();
|
|
176
|
-
|
|
177
|
-
if (userData.hasKey("email")) {
|
|
178
|
-
userDataBundle.putString("em", userData.getString("email"));
|
|
179
|
-
}
|
|
180
|
-
if (userData.hasKey("firstName")) {
|
|
181
|
-
userDataBundle.putString("fn", userData.getString("firstName"));
|
|
182
|
-
}
|
|
183
|
-
if (userData.hasKey("lastName")) {
|
|
184
|
-
userDataBundle.putString("ln", userData.getString("lastName"));
|
|
185
|
-
}
|
|
186
|
-
if (userData.hasKey("phone")) {
|
|
187
|
-
userDataBundle.putString("ph", userData.getString("phone"));
|
|
188
|
-
}
|
|
189
|
-
if (userData.hasKey("dateOfBirth")) {
|
|
190
|
-
userDataBundle.putString("db", userData.getString("dateOfBirth"));
|
|
191
|
-
}
|
|
192
|
-
if (userData.hasKey("gender")) {
|
|
193
|
-
userDataBundle.putString("ge", userData.getString("gender"));
|
|
194
|
-
}
|
|
195
|
-
if (userData.hasKey("city")) {
|
|
196
|
-
userDataBundle.putString("ct", userData.getString("city"));
|
|
197
|
-
}
|
|
198
|
-
if (userData.hasKey("state")) {
|
|
199
|
-
userDataBundle.putString("st", userData.getString("state"));
|
|
200
|
-
}
|
|
201
|
-
if (userData.hasKey("zip")) {
|
|
202
|
-
userDataBundle.putString("zp", userData.getString("zip"));
|
|
203
|
-
}
|
|
204
|
-
if (userData.hasKey("country")) {
|
|
205
|
-
userDataBundle.putString("country", userData.getString("country"));
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
AppEventsLogger.setUserData(
|
|
209
|
-
userData.hasKey("email") ? userData.getString("email") : null,
|
|
210
|
-
userData.hasKey("firstName") ? userData.getString("firstName") : null,
|
|
211
|
-
userData.hasKey("lastName") ? userData.getString("lastName") : null,
|
|
212
|
-
userData.hasKey("phone") ? userData.getString("phone") : null,
|
|
213
|
-
userData.hasKey("dateOfBirth") ? userData.getString("dateOfBirth") : null,
|
|
214
|
-
userData.hasKey("gender") ? userData.getString("gender") : null,
|
|
215
|
-
userData.hasKey("city") ? userData.getString("city") : null,
|
|
216
|
-
userData.hasKey("state") ? userData.getString("state") : null,
|
|
217
|
-
userData.hasKey("zip") ? userData.getString("zip") : null,
|
|
218
|
-
userData.hasKey("country") ? userData.getString("country") : null
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
Log.d(TAG, "Meta user data set for Advanced Matching");
|
|
222
|
-
promise.resolve(true);
|
|
223
|
-
} catch (Exception e) {
|
|
224
|
-
Log.e(TAG, "Failed to set Meta user data", e);
|
|
225
|
-
promise.reject("meta_userdata_error", "Failed to set Meta user data: " + e.getMessage());
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
@ReactMethod
|
|
230
|
-
public void clearMetaUserData(Promise promise) {
|
|
231
|
-
if (!metaInitialized) {
|
|
232
|
-
promise.resolve(false);
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
AppEventsLogger.clearUserData();
|
|
238
|
-
Log.d(TAG, "Meta user data cleared");
|
|
239
|
-
promise.resolve(true);
|
|
240
|
-
} catch (Exception e) {
|
|
241
|
-
Log.e(TAG, "Failed to clear Meta user data", e);
|
|
242
|
-
promise.reject("meta_clear_error", "Failed to clear Meta user data: " + e.getMessage());
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
@ReactMethod
|
|
247
|
-
public void updateMetaTrackingAuthorization(boolean enabled, Promise promise) {
|
|
248
|
-
try {
|
|
249
|
-
FacebookSdk.setAdvertiserIDCollectionEnabled(enabled);
|
|
250
|
-
Log.d(TAG, "Meta tracking authorization updated: " + enabled);
|
|
251
|
-
promise.resolve(true);
|
|
252
|
-
} catch (Exception e) {
|
|
253
|
-
Log.e(TAG, "Failed to update Meta tracking authorization", e);
|
|
254
|
-
promise.reject("meta_tracking_error", "Failed to update Meta tracking: " + e.getMessage());
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// ============================================================================
|
|
259
|
-
// TikTok SDK Methods
|
|
260
|
-
// ============================================================================
|
|
261
|
-
|
|
262
|
-
@ReactMethod
|
|
263
|
-
public void initializeTikTokSDK(String appId, String tiktokAppId, String accessToken, boolean debug, Promise promise) {
|
|
264
|
-
try {
|
|
265
|
-
TTConfig config = new TTConfig(reactContext.getApplicationContext())
|
|
266
|
-
.setAppId(appId)
|
|
267
|
-
.setTTAppId(tiktokAppId);
|
|
268
|
-
|
|
269
|
-
if (accessToken != null && !accessToken.isEmpty()) {
|
|
270
|
-
config.setAccessToken(accessToken);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (debug) {
|
|
274
|
-
config.openDebugMode();
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
TikTokBusinessSdk.initializeSdk(config);
|
|
278
|
-
tiktokInitialized = true;
|
|
279
|
-
|
|
280
|
-
Log.d(TAG, "TikTok SDK initialized with App ID: " + tiktokAppId);
|
|
281
|
-
promise.resolve(true);
|
|
282
|
-
} catch (Exception e) {
|
|
283
|
-
Log.e(TAG, "Failed to initialize TikTok SDK", e);
|
|
284
|
-
promise.reject("tiktok_init_error", "Failed to initialize TikTok SDK: " + e.getMessage());
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
@ReactMethod
|
|
289
|
-
public void trackTikTokEvent(String eventName, String eventId, ReadableMap properties, Promise promise) {
|
|
290
|
-
if (!tiktokInitialized) {
|
|
291
|
-
promise.resolve(false);
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
try {
|
|
296
|
-
TikTokAppEvent event;
|
|
297
|
-
if (eventId != null && !eventId.isEmpty()) {
|
|
298
|
-
event = new TikTokAppEvent(eventName).setEventId(eventId);
|
|
299
|
-
} else {
|
|
300
|
-
event = new TikTokAppEvent(eventName);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Add properties to the event
|
|
304
|
-
if (properties != null) {
|
|
305
|
-
ReadableMapKeySetIterator iterator = properties.keySetIterator();
|
|
306
|
-
while (iterator.hasNextKey()) {
|
|
307
|
-
String key = iterator.nextKey();
|
|
308
|
-
switch (properties.getType(key)) {
|
|
309
|
-
case String:
|
|
310
|
-
event.addProperty(key, properties.getString(key));
|
|
311
|
-
break;
|
|
312
|
-
case Number:
|
|
313
|
-
event.addProperty(key, properties.getDouble(key));
|
|
314
|
-
break;
|
|
315
|
-
case Boolean:
|
|
316
|
-
event.addProperty(key, properties.getBoolean(key));
|
|
317
|
-
break;
|
|
318
|
-
default:
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
TikTokBusinessSdk.trackTTEvent(event);
|
|
325
|
-
|
|
326
|
-
Log.d(TAG, "TikTok event logged: " + eventName);
|
|
327
|
-
promise.resolve(true);
|
|
328
|
-
} catch (Exception e) {
|
|
329
|
-
Log.e(TAG, "Failed to log TikTok event", e);
|
|
330
|
-
promise.reject("tiktok_event_error", "Failed to log TikTok event: " + e.getMessage());
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
@ReactMethod
|
|
335
|
-
public void identifyTikTokUser(String externalId, String externalUserName, String phoneNumber, String email, Promise promise) {
|
|
336
|
-
if (!tiktokInitialized) {
|
|
337
|
-
promise.resolve(false);
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
try {
|
|
342
|
-
TikTokBusinessSdk.identify(
|
|
343
|
-
externalId != null && !externalId.isEmpty() ? externalId : null,
|
|
344
|
-
externalUserName != null && !externalUserName.isEmpty() ? externalUserName : null,
|
|
345
|
-
phoneNumber != null && !phoneNumber.isEmpty() ? phoneNumber : null,
|
|
346
|
-
email != null && !email.isEmpty() ? email : null
|
|
347
|
-
);
|
|
348
|
-
|
|
349
|
-
Log.d(TAG, "TikTok user identified");
|
|
350
|
-
promise.resolve(true);
|
|
351
|
-
} catch (Exception e) {
|
|
352
|
-
Log.e(TAG, "Failed to identify TikTok user", e);
|
|
353
|
-
promise.reject("tiktok_identify_error", "Failed to identify TikTok user: " + e.getMessage());
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
@ReactMethod
|
|
358
|
-
public void logoutTikTok(Promise promise) {
|
|
359
|
-
if (!tiktokInitialized) {
|
|
360
|
-
promise.resolve(false);
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
try {
|
|
365
|
-
TikTokBusinessSdk.logout();
|
|
366
|
-
Log.d(TAG, "TikTok user logged out");
|
|
367
|
-
promise.resolve(true);
|
|
368
|
-
} catch (Exception e) {
|
|
369
|
-
Log.e(TAG, "Failed to logout TikTok user", e);
|
|
370
|
-
promise.reject("tiktok_logout_error", "Failed to logout TikTok user: " + e.getMessage());
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
@ReactMethod
|
|
375
|
-
public void updateTikTokTrackingAuthorization(boolean enabled, Promise promise) {
|
|
376
|
-
// TikTok SDK handles this automatically on Android
|
|
377
|
-
// No explicit method needed
|
|
378
|
-
Log.d(TAG, "TikTok tracking authorization update requested: " + enabled);
|
|
379
|
-
promise.resolve(true);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
36
|
// ============================================================================
|
|
383
37
|
// SDK Availability
|
|
384
38
|
// ============================================================================
|
|
@@ -386,8 +40,6 @@ public class DatalyrNativeModule extends ReactContextBaseJavaModule {
|
|
|
386
40
|
@ReactMethod
|
|
387
41
|
public void getSDKAvailability(Promise promise) {
|
|
388
42
|
WritableMap result = Arguments.createMap();
|
|
389
|
-
result.putBoolean("meta", true);
|
|
390
|
-
result.putBoolean("tiktok", true);
|
|
391
43
|
result.putBoolean("playInstallReferrer", true);
|
|
392
44
|
// Apple Search Ads is iOS only
|
|
393
45
|
result.putBoolean("appleSearchAds", false);
|
|
@@ -434,34 +86,4 @@ public class DatalyrNativeModule extends ReactContextBaseJavaModule {
|
|
|
434
86
|
}
|
|
435
87
|
}).start();
|
|
436
88
|
}
|
|
437
|
-
|
|
438
|
-
// ============================================================================
|
|
439
|
-
// Helper Methods
|
|
440
|
-
// ============================================================================
|
|
441
|
-
|
|
442
|
-
private Bundle readableMapToBundle(ReadableMap map) {
|
|
443
|
-
Bundle bundle = new Bundle();
|
|
444
|
-
if (map == null) {
|
|
445
|
-
return bundle;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
ReadableMapKeySetIterator iterator = map.keySetIterator();
|
|
449
|
-
while (iterator.hasNextKey()) {
|
|
450
|
-
String key = iterator.nextKey();
|
|
451
|
-
switch (map.getType(key)) {
|
|
452
|
-
case String:
|
|
453
|
-
bundle.putString(key, map.getString(key));
|
|
454
|
-
break;
|
|
455
|
-
case Number:
|
|
456
|
-
bundle.putDouble(key, map.getDouble(key));
|
|
457
|
-
break;
|
|
458
|
-
case Boolean:
|
|
459
|
-
bundle.putBoolean(key, map.getBoolean(key));
|
|
460
|
-
break;
|
|
461
|
-
default:
|
|
462
|
-
break;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return bundle;
|
|
466
|
-
}
|
|
467
89
|
}
|
|
@@ -11,7 +11,7 @@ import java.util.List;
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* React Native Package for Datalyr SDK
|
|
14
|
-
* Registers
|
|
14
|
+
* Registers native modules (Datalyr, Play Install Referrer)
|
|
15
15
|
*/
|
|
16
16
|
public class DatalyrPackage implements ReactPackage {
|
|
17
17
|
|