expo-facebook-analytics 1.0.6 โ 1.1.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/README.md +36 -196
- package/android/CMakeLists.txt +16 -0
- package/android/build.gradle +36 -11
- package/android/src/main/cpp/cpp-adapter.cpp +14 -0
- package/android/src/main/java/com/nitrofbanalytics/FacebookAnalyticsPackage.kt +30 -0
- package/android/src/main/java/com/nitrofbanalytics/HybridFacebookAnalytics.kt +63 -8
- package/expo-facebook-analytics.podspec +1 -1
- package/ios/HybridFacebookAnalytics.swift +54 -9
- package/lib/index.d.ts +33 -0
- package/lib/index.js +76 -19
- package/lib/specs/FacebookAnalytics.nitro.d.ts +10 -0
- package/nitro.json +8 -2
- package/nitrogen/generated/android/NitroFBAnalyticsOnLoad.cpp +2 -2
- package/nitrogen/generated/android/c++/JHybridFacebookAnalyticsSpec.cpp +24 -0
- package/nitrogen/generated/android/c++/JHybridFacebookAnalyticsSpec.hpp +8 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitrofbanalytics/HybridFacebookAnalyticsSpec.kt +24 -0
- package/nitrogen/generated/ios/NitroFBAnalytics+autolinking.rb +2 -0
- package/nitrogen/generated/ios/c++/HybridFacebookAnalyticsSpecSwift.hpp +36 -0
- package/nitrogen/generated/ios/swift/HybridFacebookAnalyticsSpec.swift +6 -0
- package/nitrogen/generated/ios/swift/HybridFacebookAnalyticsSpec_cxx.swift +66 -0
- package/nitrogen/generated/shared/c++/HybridFacebookAnalyticsSpec.cpp +6 -0
- package/nitrogen/generated/shared/c++/HybridFacebookAnalyticsSpec.hpp +6 -0
- package/package.json +9 -7
- package/plugin/build/withFacebookAnalyticsIOS.js +3 -1
- package/react-native.config.js +9 -1
- package/src/index.ts +84 -19
- package/src/specs/FacebookAnalytics.nitro.ts +12 -0
package/README.md
CHANGED
|
@@ -2,45 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
High-performance Facebook Analytics for React Native using [Nitro Modules](https://github.com/mrousavy/nitro).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
๐ **[Documentation](https://jasperaelvoet.github.io/expo-facebook-analytics/)** ยท ๐งช **[Example app](./example)**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
7
|
+
> **Minimal by design.** This library wraps only the Facebook **App Events /
|
|
8
|
+
> Analytics** APIs โ event logging, user identity, and device identifiers. It is
|
|
9
|
+
> **not** a full Facebook SDK (no Login, Sharing, Graph API, or Gaming). If you
|
|
10
|
+
> only need analytics and conversion tracking, that's the point: a tiny, fast
|
|
11
|
+
> surface area built on a zero-overhead Nitro/JSI bridge to the native SDK.
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
|
|
16
|
+
npx expo install expo-facebook-analytics react-native-nitro-modules
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```sh
|
|
22
|
-
npm install expo-facebook-analytics react-native-nitro-modules
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Peer Dependencies
|
|
26
|
-
|
|
27
|
-
- `react-native` >= 0.71
|
|
28
|
-
- `react-native-nitro-modules` >= 0.35.0
|
|
29
|
-
- `expo` >= 55.0.0 _(optional, for config plugin)_
|
|
30
|
-
|
|
31
|
-
### iOS
|
|
32
|
-
|
|
33
|
-
```sh
|
|
34
|
-
cd ios && pod install
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Android
|
|
38
|
-
|
|
39
|
-
No additional steps required โ Gradle handles the Facebook SDK dependency automatically.
|
|
40
|
-
|
|
41
|
-
## Expo Setup
|
|
42
|
-
|
|
43
|
-
Add the plugin to your `app.json` / `app.config.js`:
|
|
19
|
+
Add the config plugin to your `app.json`:
|
|
44
20
|
|
|
45
21
|
```json
|
|
46
22
|
{
|
|
@@ -50,8 +26,7 @@ Add the plugin to your `app.json` / `app.config.js`:
|
|
|
50
26
|
"expo-facebook-analytics",
|
|
51
27
|
{
|
|
52
28
|
"appID": "YOUR_FACEBOOK_APP_ID",
|
|
53
|
-
"clientToken": "YOUR_FACEBOOK_CLIENT_TOKEN"
|
|
54
|
-
"displayName": "Your App Name"
|
|
29
|
+
"clientToken": "YOUR_FACEBOOK_CLIENT_TOKEN"
|
|
55
30
|
}
|
|
56
31
|
]
|
|
57
32
|
]
|
|
@@ -59,183 +34,48 @@ Add the plugin to your `app.json` / `app.config.js`:
|
|
|
59
34
|
}
|
|
60
35
|
```
|
|
61
36
|
|
|
62
|
-
|
|
37
|
+
The module ships native code, so it requires a [development build](https://docs.expo.dev/develop/development-builds/introduction/) โ it can't run in Expo Go.
|
|
63
38
|
|
|
64
|
-
|
|
65
|
-
| ------------------------------- | --------------------- | ------------- | ------------------------------------------ |
|
|
66
|
-
| `appID` | `string` | **required** | Facebook App ID |
|
|
67
|
-
| `clientToken` | `string` | **required** | Facebook Client Token |
|
|
68
|
-
| `displayName` | `string` | App name | Display name for Facebook |
|
|
69
|
-
| `scheme` | `string` | `fb{appID}` | URL scheme for deep linking |
|
|
70
|
-
| `isAutoInitEnabled` | `boolean` | `true` | Auto-initialize Facebook SDK |
|
|
71
|
-
| `autoLogAppEventsEnabled` | `boolean` | `true` | Automatically log app events |
|
|
72
|
-
| `advertiserIDCollectionEnabled` | `boolean` | `true` | Enable advertiser ID collection |
|
|
73
|
-
| `iosUserTrackingPermission` | `string` \| `false` | ATT prompt | Custom tracking permission text or disable |
|
|
74
|
-
|
|
75
|
-
### Manual Native Setup
|
|
76
|
-
|
|
77
|
-
If you're not using Expo, refer to the [Facebook SDK documentation](https://developers.facebook.com/docs/app-events/getting-started-app-events-android/) for manual iOS and Android configuration.
|
|
78
|
-
|
|
79
|
-
## Usage
|
|
80
|
-
|
|
81
|
-
### Log Events
|
|
39
|
+
## Quick start
|
|
82
40
|
|
|
83
41
|
```typescript
|
|
84
|
-
import { logEvent, logPurchase, AppEvents
|
|
42
|
+
import { logEvent, logPurchase, AppEvents } from 'expo-facebook-analytics';
|
|
85
43
|
|
|
86
|
-
// Simple event
|
|
87
44
|
logEvent(AppEvents.ViewedContent);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
logEvent(AppEvents.Searched, 1);
|
|
91
|
-
|
|
92
|
-
// Event with parameters
|
|
93
|
-
logEvent(AppEvents.AddedToCart, {
|
|
94
|
-
[AppEventParams.ContentID]: 'product-123',
|
|
95
|
-
[AppEventParams.ContentType]: 'product',
|
|
96
|
-
[AppEventParams.Currency]: 'USD',
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// Event with value and parameters
|
|
100
|
-
logEvent(AppEvents.Purchased, 29.99, {
|
|
101
|
-
[AppEventParams.Currency]: 'USD',
|
|
102
|
-
[AppEventParams.NumItems]: 2,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Log a purchase
|
|
106
|
-
logPurchase(29.99, 'USD', {
|
|
107
|
-
[AppEventParams.ContentID]: 'product-123',
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Log push notification open
|
|
111
|
-
logPushNotificationOpen({ campaign: 'summer-sale' });
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### User Identity
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
import { setUserID, getUserID, clearUserID, setUserData } from 'expo-facebook-analytics';
|
|
118
|
-
|
|
119
|
-
// Set user ID for analytics
|
|
120
|
-
setUserID('user-123');
|
|
121
|
-
|
|
122
|
-
// Get current user ID
|
|
123
|
-
const userId = getUserID();
|
|
124
|
-
|
|
125
|
-
// Clear user ID
|
|
126
|
-
clearUserID();
|
|
127
|
-
|
|
128
|
-
// Set user data for advanced matching
|
|
129
|
-
setUserData({
|
|
130
|
-
email: 'user@example.com',
|
|
131
|
-
firstName: 'John',
|
|
132
|
-
lastName: 'Doe',
|
|
133
|
-
gender: 'm',
|
|
134
|
-
city: 'San Francisco',
|
|
135
|
-
state: 'CA',
|
|
136
|
-
country: 'US',
|
|
137
|
-
});
|
|
45
|
+
logEvent(AppEvents.AddedToCart, { product: 'sku-123' });
|
|
46
|
+
logPurchase(29.99, 'USD');
|
|
138
47
|
```
|
|
139
48
|
|
|
140
|
-
|
|
49
|
+
For deferred (consent-gated) initialization, set `isAutoInitEnabled: false` in the
|
|
50
|
+
plugin and call `initialize()` yourself. Enable the Facebook SDK's native logging
|
|
51
|
+
with `setLoggingEnabled(true)`. See the [documentation](https://jasperaelvoet.github.io/expo-facebook-analytics/) for the full API.
|
|
141
52
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const anonId = await getAnonymousID();
|
|
146
|
-
const advertiserId = await getAdvertiserID(); // IDFA on iOS, AAID on Android
|
|
147
|
-
```
|
|
53
|
+
See the **[documentation](https://jasperaelvoet.github.io/expo-facebook-analytics/)** for the full API,
|
|
54
|
+
config-plugin options, manual initialization, and predefined constants.
|
|
148
55
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
```typescript
|
|
152
|
-
import { setFlushBehavior, flush, setPushNotificationsDeviceToken, setPushNotificationsRegistrationId } from 'expo-facebook-analytics';
|
|
153
|
-
|
|
154
|
-
// Control event batching: 'auto' (default) or 'explicit_only'
|
|
155
|
-
setFlushBehavior('explicit_only');
|
|
156
|
-
|
|
157
|
-
// Manually flush queued events
|
|
158
|
-
flush();
|
|
159
|
-
|
|
160
|
-
// Push notification tokens
|
|
161
|
-
setPushNotificationsDeviceToken(apnsToken); // iOS
|
|
162
|
-
setPushNotificationsRegistrationId(fcmToken); // Android
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## API Reference
|
|
166
|
-
|
|
167
|
-
### Event Logging
|
|
168
|
-
|
|
169
|
-
| Function | Description |
|
|
170
|
-
| --------------------------- | ------------------------------------ |
|
|
171
|
-
| `logEvent(name, ...args)` | Log a custom or predefined event |
|
|
172
|
-
| `logPurchase(amount, currency, params?)` | Log a purchase event |
|
|
173
|
-
| `logPushNotificationOpen(payload?)` | Log a push notification open |
|
|
174
|
-
|
|
175
|
-
### User Identity
|
|
176
|
-
|
|
177
|
-
| Function | Description |
|
|
178
|
-
| ----------------------- | ---------------------------------- |
|
|
179
|
-
| `setUserID(id)` | Set the user ID for analytics |
|
|
180
|
-
| `clearUserID()` | Clear the current user ID |
|
|
181
|
-
| `getUserID()` | Get the current user ID |
|
|
182
|
-
| `setUserData(data)` | Set user data for advanced matching|
|
|
183
|
-
|
|
184
|
-
### Device Identifiers
|
|
185
|
-
|
|
186
|
-
| Function | Description |
|
|
187
|
-
| --------------------- | ------------------------------------------- |
|
|
188
|
-
| `getAnonymousID()` | Get the anonymous device ID |
|
|
189
|
-
| `getAdvertiserID()` | Get IDFA (iOS) or AAID (Android) |
|
|
190
|
-
|
|
191
|
-
### Configuration
|
|
192
|
-
|
|
193
|
-
| Function | Description |
|
|
194
|
-
| ------------------------------------- | ---------------------------------- |
|
|
195
|
-
| `setFlushBehavior(behavior)` | Set event flush behavior |
|
|
196
|
-
| `flush()` | Flush queued events immediately |
|
|
197
|
-
| `setPushNotificationsDeviceToken(t)` | Set APNs push token (iOS) |
|
|
198
|
-
| `setPushNotificationsRegistrationId(id)` | Set FCM registration ID (Android) |
|
|
199
|
-
|
|
200
|
-
## Predefined Constants
|
|
201
|
-
|
|
202
|
-
### AppEvents
|
|
203
|
-
|
|
204
|
-
`AchievedLevel`, `AdClick`, `AdImpression`, `AddedPaymentInfo`, `AddedToCart`, `AddedToWishlist`, `CompletedRegistration`, `CompletedTutorial`, `Contact`, `CustomizeProduct`, `Donate`, `FindLocation`, `InitiatedCheckout`, `Purchased`, `Rated`, `Schedule`, `Searched`, `SpentCredits`, `StartTrial`, `SubmitApplication`, `Subscribe`, `UnlockedAchievement`, `ViewedContent`
|
|
56
|
+
## Requirements
|
|
205
57
|
|
|
206
|
-
|
|
58
|
+
| Tool | Version |
|
|
59
|
+
| ---------------------------- | ------- |
|
|
60
|
+
| Expo SDK | 56+ |
|
|
61
|
+
| React Native | 0.85+ |
|
|
62
|
+
| `react-native-nitro-modules` | 0.35.9+ |
|
|
63
|
+
| iOS deployment target | 16.4+ |
|
|
64
|
+
| Android `minSdkVersion` | 24+ |
|
|
207
65
|
|
|
208
|
-
|
|
66
|
+
Native SDKs: Facebook iOS/Android SDK 18. Requires the React Native New Architecture (default in SDK 56).
|
|
209
67
|
|
|
210
|
-
##
|
|
68
|
+
## Contributing
|
|
211
69
|
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
lastName?: string;
|
|
219
|
-
phone?: string;
|
|
220
|
-
dateOfBirth?: string;
|
|
221
|
-
gender?: 'm' | 'f';
|
|
222
|
-
city?: string;
|
|
223
|
-
state?: string;
|
|
224
|
-
zip?: string;
|
|
225
|
-
country?: string;
|
|
226
|
-
}>;
|
|
227
|
-
|
|
228
|
-
type AppEventsFlushBehavior = 'auto' | 'explicit_only';
|
|
70
|
+
```sh
|
|
71
|
+
bun install # install dependencies
|
|
72
|
+
bun run nitrogen # regenerate native bindings
|
|
73
|
+
bun run prepare # build the library
|
|
74
|
+
bun test # run tests
|
|
75
|
+
bun run check # lint & format
|
|
229
76
|
```
|
|
230
77
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
| Platform | Minimum Version |
|
|
234
|
-
| -------- | --------------- |
|
|
235
|
-
| iOS | 13.0 |
|
|
236
|
-
| Android | SDK 21 |
|
|
237
|
-
|
|
238
|
-
Native SDKs: Facebook SDK ~17.0
|
|
78
|
+
To run the example app, see [`example/`](./example).
|
|
239
79
|
|
|
240
80
|
## License
|
|
241
81
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
project(NitroFBAnalytics)
|
|
2
|
+
cmake_minimum_required(VERSION 3.9.0)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
5
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
6
|
+
|
|
7
|
+
# The shared library loaded by NitroFBAnalyticsOnLoad.initializeNative()
|
|
8
|
+
# (System.loadLibrary("NitroFBAnalytics")). Its real sources are added by the
|
|
9
|
+
# generated autolinking cmake below.
|
|
10
|
+
add_library(NitroFBAnalytics SHARED
|
|
11
|
+
src/main/cpp/cpp-adapter.cpp
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Adds the Nitrogen-generated C++ sources, headers, and links (fbjni,
|
|
15
|
+
# ReactAndroid, react-native-nitro-modules) to the NitroFBAnalytics target.
|
|
16
|
+
include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroFBAnalytics+autolinking.cmake)
|
package/android/build.gradle
CHANGED
|
@@ -7,44 +7,61 @@ buildscript {
|
|
|
7
7
|
mavenCentral()
|
|
8
8
|
}
|
|
9
9
|
dependencies {
|
|
10
|
-
classpath("com.android.tools.build:gradle
|
|
11
|
-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin
|
|
10
|
+
classpath("com.android.tools.build:gradle:${safeExtGet('androidGradlePluginVersion', '8.9.2')}")
|
|
11
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', '2.1.20')}")
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
apply plugin: 'com.android.library'
|
|
16
16
|
apply plugin: 'kotlin-android'
|
|
17
17
|
|
|
18
|
-
def nitrogenAutolinking = file("nitrogen/generated/android/NitroFBAnalytics
|
|
18
|
+
def nitrogenAutolinking = file("../nitrogen/generated/android/NitroFBAnalytics+autolinking.gradle")
|
|
19
19
|
if (nitrogenAutolinking.exists()) {
|
|
20
20
|
apply from: nitrogenAutolinking
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
android {
|
|
24
24
|
namespace 'com.nitrofbanalytics'
|
|
25
|
-
compileSdkVersion safeExtGet('compileSdkVersion',
|
|
25
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 36)
|
|
26
26
|
|
|
27
27
|
defaultConfig {
|
|
28
|
-
minSdkVersion safeExtGet('minSdkVersion',
|
|
29
|
-
targetSdkVersion safeExtGet('targetSdkVersion',
|
|
28
|
+
minSdkVersion safeExtGet('minSdkVersion', 24)
|
|
29
|
+
targetSdkVersion safeExtGet('targetSdkVersion', 36)
|
|
30
|
+
|
|
31
|
+
externalNativeBuild {
|
|
32
|
+
cmake {
|
|
33
|
+
cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-std=c++20"
|
|
34
|
+
arguments "-DANDROID_STL=c++_shared"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
buildFeatures {
|
|
40
|
+
prefab true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
externalNativeBuild {
|
|
44
|
+
cmake {
|
|
45
|
+
path "CMakeLists.txt"
|
|
46
|
+
}
|
|
30
47
|
}
|
|
31
48
|
|
|
32
49
|
sourceSets {
|
|
33
50
|
main {
|
|
34
51
|
java.srcDirs += [
|
|
35
52
|
'src/main/java',
|
|
36
|
-
'nitrogen/generated/android/kotlin'
|
|
53
|
+
'../nitrogen/generated/android/kotlin'
|
|
37
54
|
]
|
|
38
55
|
}
|
|
39
56
|
}
|
|
40
57
|
|
|
41
58
|
compileOptions {
|
|
42
|
-
sourceCompatibility JavaVersion.
|
|
43
|
-
targetCompatibility JavaVersion.
|
|
59
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
60
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
44
61
|
}
|
|
45
62
|
|
|
46
63
|
kotlinOptions {
|
|
47
|
-
jvmTarget = '
|
|
64
|
+
jvmTarget = '17'
|
|
48
65
|
}
|
|
49
66
|
}
|
|
50
67
|
|
|
@@ -55,6 +72,14 @@ repositories {
|
|
|
55
72
|
|
|
56
73
|
dependencies {
|
|
57
74
|
implementation 'com.facebook.react:react-native:+'
|
|
58
|
-
|
|
75
|
+
// react-native-nitro-modules does not publish `com.margelo.nitro:nitro-modules`
|
|
76
|
+
// to a Maven repo and autolinking doesn't substitute it, so depend on the
|
|
77
|
+
// autolinked Gradle project directly. Fall back to the coordinate for
|
|
78
|
+
// standalone builds where the project isn't part of the Gradle build.
|
|
79
|
+
if (findProject(':react-native-nitro-modules') != null) {
|
|
80
|
+
implementation project(':react-native-nitro-modules')
|
|
81
|
+
} else {
|
|
82
|
+
implementation 'com.margelo.nitro:nitro-modules:+'
|
|
83
|
+
}
|
|
59
84
|
implementation 'com.facebook.android:facebook-android-sdk:18.0.3'
|
|
60
85
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#include <jni.h>
|
|
2
|
+
#include <fbjni/fbjni.h>
|
|
3
|
+
|
|
4
|
+
#include "NitroFBAnalyticsOnLoad.hpp"
|
|
5
|
+
|
|
6
|
+
// Entry point of libNitroFBAnalytics.so. Loaded by
|
|
7
|
+
// NitroFBAnalyticsOnLoad.initializeNative() (System.loadLibrary), this
|
|
8
|
+
// registers the "FacebookAnalytics" HybridObject with the Nitro registry so
|
|
9
|
+
// JS `createHybridObject("FacebookAnalytics")` can resolve it.
|
|
10
|
+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
|
|
11
|
+
return facebook::jni::initialize(vm, [] {
|
|
12
|
+
margelo::nitro::fbanalytics::registerAllNatives();
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
package com.nitrofbanalytics
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
import com.margelo.nitro.com.nitrofbanalytics.NitroFBAnalyticsOnLoad
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* React Native autolinking entry point for the Nitro module.
|
|
11
|
+
*
|
|
12
|
+
* Unlike iOS (where Nitro auto-registers via the podspec's autolinking files),
|
|
13
|
+
* Android has no auto-load mechanism for the C++ library. This package exists
|
|
14
|
+
* solely so React Native autolinking instantiates it and triggers
|
|
15
|
+
* [NitroFBAnalyticsOnLoad.initializeNative], which loads the native library and
|
|
16
|
+
* registers the "FacebookAnalytics" HybridObject in the Nitro registry.
|
|
17
|
+
*/
|
|
18
|
+
class FacebookAnalyticsPackage : ReactPackage {
|
|
19
|
+
init {
|
|
20
|
+
NitroFBAnalyticsOnLoad.initializeNative()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
override fun createNativeModules(
|
|
24
|
+
reactContext: ReactApplicationContext,
|
|
25
|
+
): List<NativeModule> = emptyList()
|
|
26
|
+
|
|
27
|
+
override fun createViewManagers(
|
|
28
|
+
reactContext: ReactApplicationContext,
|
|
29
|
+
): List<ViewManager<*, *>> = emptyList()
|
|
30
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
package com.nitrofbanalytics
|
|
1
|
+
package com.margelo.nitro.com.nitrofbanalytics
|
|
2
2
|
|
|
3
3
|
import android.os.Bundle
|
|
4
4
|
import com.facebook.FacebookSdk
|
|
5
|
+
import com.facebook.LoggingBehavior
|
|
5
6
|
import com.facebook.appevents.AppEventsConstants
|
|
6
7
|
import com.facebook.appevents.AppEventsLogger
|
|
7
8
|
import com.facebook.internal.AttributionIdentifiers
|
|
8
9
|
import com.margelo.nitro.core.Promise
|
|
10
|
+
import kotlinx.coroutines.CoroutineScope
|
|
11
|
+
import kotlinx.coroutines.Dispatchers
|
|
9
12
|
import java.math.BigDecimal
|
|
10
13
|
import java.util.Currency
|
|
11
14
|
|
|
@@ -15,6 +18,52 @@ class HybridFacebookAnalytics : HybridFacebookAnalyticsSpec() {
|
|
|
15
18
|
AppEventsLogger.newLogger(FacebookSdk.getApplicationContext())
|
|
16
19
|
}
|
|
17
20
|
|
|
21
|
+
// Background scope for blocking SDK calls (Play Services I/O) so they never
|
|
22
|
+
// run on the JS thread.
|
|
23
|
+
private val ioScope = CoroutineScope(Dispatchers.IO)
|
|
24
|
+
|
|
25
|
+
// region Initialization & Runtime Configuration
|
|
26
|
+
|
|
27
|
+
override fun initialize() {
|
|
28
|
+
FacebookSdk.setAutoInitEnabled(true)
|
|
29
|
+
FacebookSdk.fullyInitialize()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override fun setAutoLogAppEventsEnabled(enabled: Boolean) {
|
|
33
|
+
FacebookSdk.setAutoLogAppEventsEnabled(enabled)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override fun setAdvertiserIDCollectionEnabled(enabled: Boolean) {
|
|
37
|
+
FacebookSdk.setAdvertiserIDCollectionEnabled(enabled)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override fun setAppID(appID: String) {
|
|
41
|
+
FacebookSdk.setApplicationId(appID)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun setClientToken(clientToken: String) {
|
|
45
|
+
FacebookSdk.setClientToken(clientToken)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override fun setLoggingEnabled(enabled: Boolean) {
|
|
49
|
+
val behaviors = listOf(
|
|
50
|
+
LoggingBehavior.APP_EVENTS,
|
|
51
|
+
LoggingBehavior.REQUESTS,
|
|
52
|
+
LoggingBehavior.DEVELOPER_ERRORS,
|
|
53
|
+
LoggingBehavior.INCLUDE_ACCESS_TOKENS
|
|
54
|
+
)
|
|
55
|
+
FacebookSdk.setIsDebugEnabled(enabled)
|
|
56
|
+
for (behavior in behaviors) {
|
|
57
|
+
if (enabled) {
|
|
58
|
+
FacebookSdk.addLoggingBehavior(behavior)
|
|
59
|
+
} else {
|
|
60
|
+
FacebookSdk.removeLoggingBehavior(behavior)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// endregion
|
|
66
|
+
|
|
18
67
|
// region Event Logging
|
|
19
68
|
|
|
20
69
|
override fun logEvent(eventName: String, valueToSum: Double, params: Map<String, String>) {
|
|
@@ -83,16 +132,22 @@ class HybridFacebookAnalytics : HybridFacebookAnalyticsSpec() {
|
|
|
83
132
|
// region Device Identifiers
|
|
84
133
|
|
|
85
134
|
override fun getAnonymousID(): Promise<String?> {
|
|
86
|
-
return Promise.resolved(
|
|
135
|
+
return Promise.resolved(
|
|
136
|
+
AppEventsLogger.getAnonymousAppDeviceGUID(FacebookSdk.getApplicationContext())
|
|
137
|
+
)
|
|
87
138
|
}
|
|
88
139
|
|
|
89
140
|
override fun getAdvertiserID(): Promise<String?> {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
141
|
+
// AttributionIdentifiers performs blocking Play Services I/O, so run it
|
|
142
|
+
// off the JS thread on the IO dispatcher.
|
|
143
|
+
return Promise.async(ioScope) {
|
|
144
|
+
try {
|
|
145
|
+
val context = FacebookSdk.getApplicationContext()
|
|
146
|
+
val identifiers = AttributionIdentifiers.getAttributionIdentifiers(context)
|
|
147
|
+
identifiers?.androidAdvertiserId
|
|
148
|
+
} catch (e: Exception) {
|
|
149
|
+
null
|
|
150
|
+
}
|
|
96
151
|
}
|
|
97
152
|
}
|
|
98
153
|
|
|
@@ -12,7 +12,7 @@ Pod::Spec.new do |s|
|
|
|
12
12
|
s.license = package['license']
|
|
13
13
|
s.author = 'expo-facebook-analytics contributors'
|
|
14
14
|
s.source = { :git => '.', :tag => s.version.to_s }
|
|
15
|
-
s.platforms = { :ios => '
|
|
15
|
+
s.platforms = { :ios => '16.4' }
|
|
16
16
|
s.module_name = 'NitroFBAnalytics'
|
|
17
17
|
|
|
18
18
|
s.source_files = [
|
|
@@ -5,6 +5,43 @@ import AdSupport
|
|
|
5
5
|
|
|
6
6
|
class HybridFacebookAnalytics: HybridFacebookAnalyticsSpec {
|
|
7
7
|
|
|
8
|
+
// MARK: - Initialization & Runtime Configuration
|
|
9
|
+
|
|
10
|
+
func initialize() throws {
|
|
11
|
+
// On iOS, auto-init is controlled by Info.plist (FacebookAutoInitEnabled).
|
|
12
|
+
// When disabled, this performs the deferred initialization.
|
|
13
|
+
ApplicationDelegate.shared.initializeSDK()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func setAutoLogAppEventsEnabled(enabled: Bool) throws {
|
|
17
|
+
Settings.shared.isAutoLogAppEventsEnabled = enabled
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
func setAdvertiserIDCollectionEnabled(enabled: Bool) throws {
|
|
21
|
+
Settings.shared.isAdvertiserIDCollectionEnabled = enabled
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
func setAppID(appID: String) throws {
|
|
25
|
+
Settings.shared.appID = appID
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
func setClientToken(clientToken: String) throws {
|
|
29
|
+
Settings.shared.clientToken = clientToken
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func setLoggingEnabled(enabled: Bool) throws {
|
|
33
|
+
let behaviors: [LoggingBehavior] = [
|
|
34
|
+
.appEvents, .networkRequests, .developerErrors, .informational,
|
|
35
|
+
]
|
|
36
|
+
for behavior in behaviors {
|
|
37
|
+
if enabled {
|
|
38
|
+
Settings.shared.enableLoggingBehavior(behavior)
|
|
39
|
+
} else {
|
|
40
|
+
Settings.shared.disableLoggingBehavior(behavior)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
8
45
|
// MARK: - Event Logging
|
|
9
46
|
|
|
10
47
|
func logEvent(eventName: String, valueToSum: Double, params: [String: String]) throws {
|
|
@@ -115,16 +152,24 @@ class HybridFacebookAnalytics: HybridFacebookAnalyticsSpec {
|
|
|
115
152
|
// MARK: - Push Notifications
|
|
116
153
|
|
|
117
154
|
func setPushNotificationsDeviceToken(token: String) throws {
|
|
118
|
-
// Token comes as a hex string โ convert back to raw Data
|
|
119
|
-
|
|
120
|
-
var data = Data()
|
|
121
|
-
var
|
|
122
|
-
|
|
123
|
-
let
|
|
124
|
-
|
|
125
|
-
|
|
155
|
+
// Token comes as a hex string โ convert back to raw Data.
|
|
156
|
+
// Iterate over UTF-8 bytes and pack each pair of hex digits into one byte.
|
|
157
|
+
var data = Data(capacity: token.utf8.count / 2)
|
|
158
|
+
var highNibble: UInt8? = nil
|
|
159
|
+
for ascii in token.utf8 {
|
|
160
|
+
let nibble: UInt8
|
|
161
|
+
switch ascii {
|
|
162
|
+
case 0x30...0x39: nibble = ascii - 0x30 // '0'-'9'
|
|
163
|
+
case 0x41...0x46: nibble = ascii - 0x41 + 10 // 'A'-'F'
|
|
164
|
+
case 0x61...0x66: nibble = ascii - 0x61 + 10 // 'a'-'f'
|
|
165
|
+
default: continue // skip spaces / non-hex
|
|
166
|
+
}
|
|
167
|
+
if let high = highNibble {
|
|
168
|
+
data.append((high << 4) | nibble)
|
|
169
|
+
highNibble = nil
|
|
170
|
+
} else {
|
|
171
|
+
highNibble = nibble
|
|
126
172
|
}
|
|
127
|
-
index = nextIndex
|
|
128
173
|
}
|
|
129
174
|
AppEvents.shared.setPushNotificationsDeviceToken(data)
|
|
130
175
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import type { AppEventsFlushBehavior, Params, UserData } from "./types";
|
|
2
2
|
export type { AppEventsFlushBehavior, Params, UserData } from "./types";
|
|
3
3
|
export { AppEventParams, AppEvents } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Manually initialize the Facebook SDK.
|
|
6
|
+
*
|
|
7
|
+
* Only required when `isAutoInitEnabled` is set to `false` in the config plugin.
|
|
8
|
+
* Call this once, early in your app's lifecycle (e.g. in your root layout),
|
|
9
|
+
* after optionally configuring the app ID / client token at runtime.
|
|
10
|
+
*/
|
|
11
|
+
export declare function initialize(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Enable or disable automatic logging of app events at runtime.
|
|
14
|
+
*/
|
|
15
|
+
export declare function setAutoLogAppEventsEnabled(enabled: boolean): void;
|
|
16
|
+
/**
|
|
17
|
+
* Enable or disable advertiser ID (IDFA / AAID) collection at runtime.
|
|
18
|
+
*/
|
|
19
|
+
export declare function setAdvertiserIDCollectionEnabled(enabled: boolean): void;
|
|
20
|
+
/**
|
|
21
|
+
* Set the Facebook App ID at runtime (alternative to the config plugin).
|
|
22
|
+
* Call before {@link initialize} when configuring the SDK manually.
|
|
23
|
+
*/
|
|
24
|
+
export declare function setAppID(appID: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Set the Facebook Client Token at runtime (alternative to the config plugin).
|
|
27
|
+
* Call before {@link initialize} when configuring the SDK manually.
|
|
28
|
+
*/
|
|
29
|
+
export declare function setClientToken(clientToken: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Enable verbose Facebook SDK logging (app events, network requests, developer
|
|
32
|
+
* errors). Output is printed to the native console โ view it via the Xcode
|
|
33
|
+
* console / `xcrun simctl spawn booted log stream` (iOS) or `adb logcat` (Android).
|
|
34
|
+
* Intended for development only.
|
|
35
|
+
*/
|
|
36
|
+
export declare function setLoggingEnabled(enabled: boolean): void;
|
|
4
37
|
/**
|
|
5
38
|
* Log a custom or predefined app event.
|
|
6
39
|
* @param eventName - Event name (use AppEvents constants for predefined events)
|