@react-native-firebase/analytics 23.8.8 → 24.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/CHANGELOG.md +23 -0
- package/README.md +24 -0
- package/RNFBAnalytics.podspec +2 -1
- package/android/src/reactnative/java/io/invertase/firebase/analytics/ReactNativeFirebaseAnalyticsModule.java +48 -4
- package/app.plugin.js +1 -0
- package/dist/module/modular.js +15 -3
- package/dist/module/modular.js.map +1 -1
- package/dist/module/namespaced.js +5 -4
- package/dist/module/namespaced.js.map +1 -1
- package/dist/module/structs.js +4 -3
- package/dist/module/structs.js.map +1 -1
- package/dist/module/types/analytics.js.map +1 -1
- package/dist/module/types/internal.js +4 -0
- package/dist/module/types/internal.js.map +1 -0
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/modular.d.ts +8 -3
- package/dist/typescript/lib/modular.d.ts.map +1 -1
- package/dist/typescript/lib/namespaced.d.ts +1 -0
- package/dist/typescript/lib/namespaced.d.ts.map +1 -1
- package/dist/typescript/lib/structs.d.ts +58 -2
- package/dist/typescript/lib/structs.d.ts.map +1 -1
- package/dist/typescript/lib/types/analytics.d.ts +2 -1
- package/dist/typescript/lib/types/analytics.d.ts.map +1 -1
- package/dist/typescript/lib/types/internal.d.ts +39 -0
- package/dist/typescript/lib/types/internal.d.ts.map +1 -0
- package/dist/typescript/lib/version.d.ts +1 -1
- package/ios/RNFBAnalytics/RNFBAnalyticsLogTransaction.swift +74 -0
- package/ios/RNFBAnalytics/RNFBAnalyticsModule.m +71 -3
- package/ios/RNFBAnalytics.xcodeproj/project.pbxproj +6 -0
- package/lib/modular.ts +17 -3
- package/lib/namespaced.ts +18 -7
- package/lib/structs.ts +3 -2
- package/lib/types/analytics.ts +2 -1
- package/lib/types/internal.ts +62 -0
- package/lib/version.ts +1 -1
- package/package.json +16 -5
- package/plugin/build/index.d.ts +4 -0
- package/plugin/build/index.js +16 -0
- package/plugin/build/ios/index.d.ts +2 -0
- package/plugin/build/ios/index.js +6 -0
- package/plugin/build/ios/podfile.d.ts +6 -0
- package/plugin/build/ios/podfile.js +45 -0
- package/plugin/build/pluginConfig.d.ts +10 -0
- package/plugin/build/pluginConfig.js +2 -0
- package/plugin/src/index.ts +18 -0
- package/plugin/src/ios/index.ts +6 -0
- package/plugin/src/ios/podfile.ts +72 -0
- package/plugin/src/pluginConfig.ts +11 -0
- package/plugin/tsconfig.json +9 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/typedoc.json +48 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Analytics } from './analytics';
|
|
2
|
+
/**
|
|
3
|
+
* Native Analytics module interface (RNFBAnalyticsModule).
|
|
4
|
+
* Matches the methods exposed by the native iOS/Android bridge.
|
|
5
|
+
* logTransaction and initiateOnDeviceConversionMeasurement* are iOS-only.
|
|
6
|
+
*/
|
|
7
|
+
export interface RNFBAnalyticsModule {
|
|
8
|
+
logEvent(name: string, params?: Record<string, unknown>): Promise<void>;
|
|
9
|
+
setUserId(userId: string | null): Promise<void>;
|
|
10
|
+
setUserProperty(key: string, value: string | null): Promise<void>;
|
|
11
|
+
setUserProperties(properties: Record<string, string | number | boolean | null>): Promise<void>;
|
|
12
|
+
setDefaultEventParameters(params?: Record<string, unknown> | null): Promise<void>;
|
|
13
|
+
setConsent(consent: Record<string, unknown>): Promise<void>;
|
|
14
|
+
setAnalyticsCollectionEnabled(enabled: boolean): Promise<void>;
|
|
15
|
+
resetAnalyticsData(): Promise<void>;
|
|
16
|
+
setSessionTimeoutDuration(milliseconds?: number): Promise<void>;
|
|
17
|
+
getAppInstanceId(): Promise<string | null>;
|
|
18
|
+
getSessionId(): Promise<number | null>;
|
|
19
|
+
/** iOS only (StoreKit 2). Not present on Android native. */
|
|
20
|
+
logTransaction(transactionId: string): Promise<void>;
|
|
21
|
+
/** iOS only. */
|
|
22
|
+
initiateOnDeviceConversionMeasurementWithEmailAddress?(emailAddress: string): Promise<void>;
|
|
23
|
+
/** iOS only. */
|
|
24
|
+
initiateOnDeviceConversionMeasurementWithHashedEmailAddress?(hashedEmailAddress: string): Promise<void>;
|
|
25
|
+
/** iOS only. */
|
|
26
|
+
initiateOnDeviceConversionMeasurementWithPhoneNumber?(phoneNumber: string): Promise<void>;
|
|
27
|
+
/** iOS only. */
|
|
28
|
+
initiateOnDeviceConversionMeasurementWithHashedPhoneNumber?(hashedPhoneNumber: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
declare module '@react-native-firebase/app/dist/module/internal/NativeModules' {
|
|
31
|
+
interface ReactNativeFirebaseNativeModules {
|
|
32
|
+
RNFBAnalyticsModule: RNFBAnalyticsModule;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Analytics instance with native module typed for modular API (e.g. logTransaction). */
|
|
36
|
+
export interface AnalyticsInternal extends Analytics {
|
|
37
|
+
readonly native: RNFBAnalyticsModule;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../../../lib/types/internal.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,yBAAyB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,yBAAyB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,4DAA4D;IAC5D,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,gBAAgB;IAChB,qDAAqD,CAAC,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,gBAAgB;IAChB,2DAA2D,CAAC,CAC1D,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,gBAAgB;IAChB,oDAAoD,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,gBAAgB;IAChB,0DAA0D,CAAC,CACzD,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,OAAO,QAAQ,+DAA+D,CAAC;IAC7E,UAAU,gCAAgC;QACxC,mBAAmB,EAAE,mBAAmB,CAAC;KAC1C;CACF;AAED,yFAAyF;AACzF,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;CACtC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "
|
|
1
|
+
export declare const version = "24.1.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import Foundation
|
|
19
|
+
import FirebaseAnalytics
|
|
20
|
+
import StoreKit
|
|
21
|
+
|
|
22
|
+
/// Swift wrapper for logging a verified StoreKit 2 transaction to Firebase Analytics.
|
|
23
|
+
/// Accessible from Objective-C; necessary because StoreKit 2 and Analytics.logTransaction use Swift async APIs.
|
|
24
|
+
/// Call from ObjC only when @available(iOS 15.0, *) (see RNFBFunctionsStreamHandler pattern).
|
|
25
|
+
@available(iOS 15.0, macOS 12.0, *)
|
|
26
|
+
@objcMembers public class RNFBAnalyticsLogTransaction: NSObject {
|
|
27
|
+
|
|
28
|
+
private static let kCode = "firebase_analytics"
|
|
29
|
+
private var logTask: Task<Void, Never>?
|
|
30
|
+
|
|
31
|
+
/// Resolve/reject types matching RCTPromiseResolveBlock / RCTPromiseRejectBlock for React Native bridge.
|
|
32
|
+
@objc public func logTransaction(
|
|
33
|
+
transactionId: String,
|
|
34
|
+
resolve: @escaping (Any?) -> Void,
|
|
35
|
+
reject: @escaping (String, String, NSError?) -> Void
|
|
36
|
+
) {
|
|
37
|
+
logTask = Task {
|
|
38
|
+
await performLogTransaction(transactionId: transactionId, resolve: resolve, reject: reject)
|
|
39
|
+
logTask = nil
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private func performLogTransaction(
|
|
44
|
+
transactionId: String,
|
|
45
|
+
resolve: @escaping (Any?) -> Void,
|
|
46
|
+
reject: @escaping (String, String, NSError?) -> Void
|
|
47
|
+
) async {
|
|
48
|
+
guard let id = UInt64(transactionId) else {
|
|
49
|
+
await MainActor.run { reject(Self.kCode, "Invalid transactionId", nil) }
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var foundTransaction: StoreKit.Transaction?
|
|
54
|
+
for await result in StoreKit.Transaction.all {
|
|
55
|
+
switch result {
|
|
56
|
+
case let .verified(transaction):
|
|
57
|
+
if transaction.id == id {
|
|
58
|
+
foundTransaction = transaction
|
|
59
|
+
break
|
|
60
|
+
}
|
|
61
|
+
case .unverified:
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
guard let transaction = foundTransaction else {
|
|
67
|
+
await MainActor.run { reject(Self.kCode, "Transaction not found", nil) }
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Analytics.logTransaction(transaction)
|
|
72
|
+
await MainActor.run { resolve(NSNull()) }
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -18,9 +18,38 @@
|
|
|
18
18
|
#import <Firebase/Firebase.h>
|
|
19
19
|
#import <React/RCTUtils.h>
|
|
20
20
|
|
|
21
|
+
#if __has_include(<RNFBAnalytics/RNFBAnalytics-Swift.h>)
|
|
22
|
+
// This import will work in situations where `use_frameworks!` is in use
|
|
23
|
+
#import <RNFBAnalytics/RNFBAnalytics-Swift.h>
|
|
24
|
+
#elif __has_include("RNFBAnalytics-Swift.h")
|
|
25
|
+
// If `use_frameworks!` is not in use (for example, while using pre-built
|
|
26
|
+
// react-native core) then header imports based on frameworks assumptions fail.
|
|
27
|
+
// So, if frameworks are not available, fall back to importing the header directly, it
|
|
28
|
+
// should be findable from a header search path pointing to the build
|
|
29
|
+
// directory. See firebase-ios-sdk#12611 for more context.
|
|
30
|
+
#import "RNFBAnalytics-Swift.h"
|
|
31
|
+
#endif
|
|
21
32
|
#import <RNFBApp/RNFBSharedUtils.h>
|
|
22
33
|
#import "RNFBAnalyticsModule.h"
|
|
23
34
|
|
|
35
|
+
/** GA4 parameters that must be sent as integer NSNumber values (not doubles from JS). */
|
|
36
|
+
static NSArray<NSString *> *RNFBAnalyticsLongNumericParameterKeys(void) {
|
|
37
|
+
static NSArray<NSString *> *keys;
|
|
38
|
+
static dispatch_once_t onceToken;
|
|
39
|
+
dispatch_once(&onceToken, ^{
|
|
40
|
+
keys = @[
|
|
41
|
+
kFIRParameterQuantity,
|
|
42
|
+
kFIRParameterIndex,
|
|
43
|
+
kFIRParameterLevel,
|
|
44
|
+
kFIRParameterNumberOfNights,
|
|
45
|
+
kFIRParameterNumberOfPassengers,
|
|
46
|
+
kFIRParameterNumberOfRooms,
|
|
47
|
+
kFIRParameterScore,
|
|
48
|
+
];
|
|
49
|
+
});
|
|
50
|
+
return keys;
|
|
51
|
+
}
|
|
52
|
+
|
|
24
53
|
@implementation RNFBAnalyticsModule
|
|
25
54
|
#pragma mark -
|
|
26
55
|
#pragma mark Module Setup
|
|
@@ -212,6 +241,18 @@ RCT_EXPORT_METHOD(initiateOnDeviceConversionMeasurementWithHashedPhoneNumber
|
|
|
212
241
|
return resolve([NSNull null]);
|
|
213
242
|
}
|
|
214
243
|
|
|
244
|
+
RCT_EXPORT_METHOD(logTransaction
|
|
245
|
+
: (NSString *)transactionId resolver
|
|
246
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
247
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
248
|
+
if (@available(iOS 15.0, macOS 12.0, *)) {
|
|
249
|
+
RNFBAnalyticsLogTransaction *handler = [[RNFBAnalyticsLogTransaction alloc] init];
|
|
250
|
+
[handler logTransactionWithTransactionId:transactionId resolve:resolve reject:reject];
|
|
251
|
+
} else {
|
|
252
|
+
reject(@"firebase_analytics", @"logTransaction() is only supported on iOS 15.0 or newer", nil);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
215
256
|
RCT_EXPORT_METHOD(setConsent
|
|
216
257
|
: (NSDictionary *)consentSettings resolver
|
|
217
258
|
: (RCTPromiseResolveBlock)resolve rejecter
|
|
@@ -245,13 +286,13 @@ RCT_EXPORT_METHOD(setConsent
|
|
|
245
286
|
[(NSArray *)newParams[kFIRParameterItems]
|
|
246
287
|
enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
|
|
247
288
|
NSMutableDictionary *item = [obj mutableCopy];
|
|
248
|
-
|
|
249
|
-
item[kFIRParameterQuantity] = @([item[kFIRParameterQuantity] integerValue]);
|
|
250
|
-
}
|
|
289
|
+
[self rnfb_coerceLongNumericParametersInMutableDictionary:item];
|
|
251
290
|
[newItems addObject:[item copy]];
|
|
252
291
|
}];
|
|
253
292
|
newParams[kFIRParameterItems] = [newItems copy];
|
|
254
293
|
}
|
|
294
|
+
[self rnfb_coerceLongNumericParametersInMutableDictionary:newParams];
|
|
295
|
+
[self rnfb_coerceSuccessParameterInMutableDictionary:newParams];
|
|
255
296
|
NSNumber *extendSession = [newParams valueForKey:kFIRParameterExtendSession];
|
|
256
297
|
if ([extendSession isEqualToNumber:@1]) {
|
|
257
298
|
newParams[kFIRParameterExtendSession] = @YES;
|
|
@@ -259,6 +300,33 @@ RCT_EXPORT_METHOD(setConsent
|
|
|
259
300
|
return [newParams copy];
|
|
260
301
|
}
|
|
261
302
|
|
|
303
|
+
- (void)rnfb_coerceLongNumericParametersInMutableDictionary:(NSMutableDictionary *)dict {
|
|
304
|
+
for (NSString *key in RNFBAnalyticsLongNumericParameterKeys()) {
|
|
305
|
+
id value = dict[key];
|
|
306
|
+
if (value != nil && value != [NSNull null]) {
|
|
307
|
+
dict[key] = @([value integerValue]);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
- (void)rnfb_coerceSuccessParameterInMutableDictionary:(NSMutableDictionary *)dict {
|
|
313
|
+
id value = dict[kFIRParameterSuccess];
|
|
314
|
+
if (value == nil || value == [NSNull null]) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
int success = 0;
|
|
318
|
+
if ([value isKindOfClass:[NSString class]]) {
|
|
319
|
+
NSString *lower = [(NSString *)value lowercaseString];
|
|
320
|
+
if ([lower isEqualToString:@"true"] || [lower isEqualToString:@"yes"] ||
|
|
321
|
+
[lower isEqualToString:@"1"]) {
|
|
322
|
+
success = 1;
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
success = [value boolValue] ? 1 : 0;
|
|
326
|
+
}
|
|
327
|
+
dict[kFIRParameterSuccess] = @(success);
|
|
328
|
+
}
|
|
329
|
+
|
|
262
330
|
/// Converts null values received over the bridge from NSNull to nil
|
|
263
331
|
/// @param value Nullable string value
|
|
264
332
|
- (NSString *)convertNSNullToNil:(NSString *)value {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
10
|
2744B98621F45429004F8E3F /* RNFBAnalyticsModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBAnalyticsModule.m */; };
|
|
11
|
+
2744B99021F45429004F8E3F /* RNFBAnalyticsLogTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98F21F45429004F8E3F /* RNFBAnalyticsLogTransaction.swift */; };
|
|
11
12
|
/* End PBXBuildFile section */
|
|
12
13
|
|
|
13
14
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
2744B98221F45429004F8E3F /* libRNFBAnalytics.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFBAnalytics.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
27
28
|
2744B98421F45429004F8E3F /* RNFBAnalyticsModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBAnalyticsModule.h; path = RNFBAnalytics/RNFBAnalyticsModule.h; sourceTree = SOURCE_ROOT; };
|
|
28
29
|
2744B98521F45429004F8E3F /* RNFBAnalyticsModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBAnalyticsModule.m; path = RNFBAnalytics/RNFBAnalyticsModule.m; sourceTree = SOURCE_ROOT; };
|
|
30
|
+
2744B98F21F45429004F8E3F /* RNFBAnalyticsLogTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBAnalyticsLogTransaction.swift; path = RNFBAnalytics/RNFBAnalyticsLogTransaction.swift; sourceTree = SOURCE_ROOT; };
|
|
29
31
|
/* End PBXFileReference section */
|
|
30
32
|
|
|
31
33
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -54,6 +56,7 @@
|
|
|
54
56
|
2744B98C21F45C64004F8E3F /* common */,
|
|
55
57
|
2744B98421F45429004F8E3F /* RNFBAnalyticsModule.h */,
|
|
56
58
|
2744B98521F45429004F8E3F /* RNFBAnalyticsModule.m */,
|
|
59
|
+
2744B98F21F45429004F8E3F /* RNFBAnalyticsLogTransaction.swift */,
|
|
57
60
|
);
|
|
58
61
|
path = RNFBAnalytics;
|
|
59
62
|
sourceTree = "<group>";
|
|
@@ -125,6 +128,7 @@
|
|
|
125
128
|
buildActionMask = 2147483647;
|
|
126
129
|
files = (
|
|
127
130
|
2744B98621F45429004F8E3F /* RNFBAnalyticsModule.m in Sources */,
|
|
131
|
+
2744B99021F45429004F8E3F /* RNFBAnalyticsLogTransaction.swift in Sources */,
|
|
128
132
|
);
|
|
129
133
|
runOnlyForDeploymentPostprocessing = 0;
|
|
130
134
|
};
|
|
@@ -166,6 +170,7 @@
|
|
|
166
170
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
167
171
|
SDKROOT = iphoneos;
|
|
168
172
|
SKIP_INSTALL = YES;
|
|
173
|
+
SWIFT_VERSION = 5.0;
|
|
169
174
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
170
175
|
};
|
|
171
176
|
name = Debug;
|
|
@@ -200,6 +205,7 @@
|
|
|
200
205
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
201
206
|
SDKROOT = iphoneos;
|
|
202
207
|
SKIP_INSTALL = YES;
|
|
208
|
+
SWIFT_VERSION = 5.0;
|
|
203
209
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
204
210
|
VALIDATE_PRODUCT = YES;
|
|
205
211
|
};
|
package/lib/modular.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/dist/module/common';
|
|
2
2
|
import { getApp } from '@react-native-firebase/app';
|
|
3
3
|
import type { Analytics } from './types/analytics';
|
|
4
|
+
import type { AnalyticsInternal } from './types/internal';
|
|
4
5
|
import { Platform } from 'react-native';
|
|
5
6
|
import type { ReactNativeFirebase } from '@react-native-firebase/app';
|
|
6
7
|
import type {
|
|
@@ -416,6 +417,18 @@ export function logEvent(
|
|
|
416
417
|
return analytics.logEvent.call(analytics, name, params, options, MODULAR_DEPRECATION_ARG);
|
|
417
418
|
}
|
|
418
419
|
|
|
420
|
+
/** Logs verified in-app purchase events in Google Analytics for Firebase
|
|
421
|
+
* after a purchase is successful.
|
|
422
|
+
* Modular API only; iOS only (StoreKit 2). Throws on Android and web before reaching native.
|
|
423
|
+
*/
|
|
424
|
+
export function logTransaction(analytics: Analytics, transaction_id: string): Promise<void> {
|
|
425
|
+
if (Platform.OS !== 'ios') {
|
|
426
|
+
return Promise.reject(new Error('logTransaction is only available on iOS'));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return (analytics as AnalyticsInternal).native.logTransaction(transaction_id);
|
|
430
|
+
}
|
|
431
|
+
|
|
419
432
|
/**
|
|
420
433
|
* If true, allows the device to collect analytical data and send it to Firebase. Useful for GDPR.
|
|
421
434
|
*/
|
|
@@ -935,10 +948,10 @@ export function initiateOnDeviceConversionMeasurementWithEmailAddress(
|
|
|
935
948
|
* start privacy-sensitive on-device conversion management.
|
|
936
949
|
* This is iOS-only.
|
|
937
950
|
* This is a no-op if you do not include '$RNFirebaseAnalyticsGoogleAppMeasurementOnDeviceConversion = true' in your Podfile
|
|
951
|
+
* {@link https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3#use-hashed-credentials}
|
|
938
952
|
*
|
|
939
953
|
* @param analytics Analytics instance.
|
|
940
954
|
* @param hashedEmailAddress sha256-hashed of normalized email address, properly formatted complete with domain name e.g, 'user@example.com'
|
|
941
|
-
* @link https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3#use-hashed-credentials
|
|
942
955
|
*/
|
|
943
956
|
export function initiateOnDeviceConversionMeasurementWithHashedEmailAddress(
|
|
944
957
|
analytics: Analytics,
|
|
@@ -975,10 +988,10 @@ export function initiateOnDeviceConversionMeasurementWithPhoneNumber(
|
|
|
975
988
|
* start privacy-sensitive on-device conversion management.
|
|
976
989
|
* This is iOS-only.
|
|
977
990
|
* This is a no-op if you do not include '$RNFirebaseAnalyticsGoogleAppMeasurementOnDeviceConversion = true' in your Podfile
|
|
991
|
+
* {@link https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3#use-hashed-credentials}
|
|
978
992
|
*
|
|
979
993
|
* @param analytics Analytics instance.
|
|
980
994
|
* @param hashedPhoneNumber sha256-hashed of normalized phone number in E.164 format - that is a leading + sign, then up to 15 digits, no dashes or spaces.
|
|
981
|
-
* @link https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3#use-hashed-credentials
|
|
982
995
|
*/
|
|
983
996
|
export function initiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
|
|
984
997
|
analytics: Analytics,
|
|
@@ -1018,9 +1031,10 @@ export function setConsent(analytics: Analytics, consentSettings: ConsentSetting
|
|
|
1018
1031
|
/**
|
|
1019
1032
|
* Configures Firebase Analytics to use custom gtag or dataLayer names.
|
|
1020
1033
|
* Intended to be used if gtag.js script has been installed on this page independently of Firebase Analytics, and is using non-default names for either the gtag function or for dataLayer. Must be called before calling `getAnalytics()` or it won't have any effect. Web only.
|
|
1021
|
-
* @param {SettingsOptions}
|
|
1034
|
+
* @param {SettingsOptions} _options - See SettingsOptions - currently unused.
|
|
1022
1035
|
* @returns {void}
|
|
1023
1036
|
*/
|
|
1037
|
+
|
|
1024
1038
|
export function settings(_options: SettingsOptions): void {
|
|
1025
1039
|
// Returns nothing until Web implemented.
|
|
1026
1040
|
}
|
package/lib/namespaced.ts
CHANGED
|
@@ -34,6 +34,8 @@ import {
|
|
|
34
34
|
getFirebaseRoot,
|
|
35
35
|
} from '@react-native-firebase/app/dist/module/internal';
|
|
36
36
|
|
|
37
|
+
import './types/internal';
|
|
38
|
+
|
|
37
39
|
// Internal types are now available through module declarations in app package
|
|
38
40
|
import { setReactNativeModule } from '@react-native-firebase/app/dist/module/internal/nativeModule';
|
|
39
41
|
import { isBoolean } from '@react-native-firebase/app/dist/module/common';
|
|
@@ -122,7 +124,7 @@ const namespace = 'analytics';
|
|
|
122
124
|
|
|
123
125
|
const nativeModuleName = 'RNFBAnalyticsModule';
|
|
124
126
|
|
|
125
|
-
class FirebaseAnalyticsModule extends FirebaseModule {
|
|
127
|
+
class FirebaseAnalyticsModule extends FirebaseModule<typeof nativeModuleName> {
|
|
126
128
|
logEvent(
|
|
127
129
|
name: string,
|
|
128
130
|
params: { [key: string]: any } = {},
|
|
@@ -800,7 +802,10 @@ class FirebaseAnalyticsModule extends FirebaseModule {
|
|
|
800
802
|
return Promise.resolve();
|
|
801
803
|
}
|
|
802
804
|
|
|
803
|
-
return
|
|
805
|
+
return (
|
|
806
|
+
this.native.initiateOnDeviceConversionMeasurementWithEmailAddress?.(emailAddress) ??
|
|
807
|
+
Promise.resolve()
|
|
808
|
+
);
|
|
804
809
|
}
|
|
805
810
|
|
|
806
811
|
initiateOnDeviceConversionMeasurementWithHashedEmailAddress(
|
|
@@ -816,8 +821,10 @@ class FirebaseAnalyticsModule extends FirebaseModule {
|
|
|
816
821
|
return Promise.resolve();
|
|
817
822
|
}
|
|
818
823
|
|
|
819
|
-
return
|
|
820
|
-
|
|
824
|
+
return (
|
|
825
|
+
this.native.initiateOnDeviceConversionMeasurementWithHashedEmailAddress?.(
|
|
826
|
+
hashedEmailAddress,
|
|
827
|
+
) ?? Promise.resolve()
|
|
821
828
|
);
|
|
822
829
|
}
|
|
823
830
|
|
|
@@ -832,7 +839,10 @@ class FirebaseAnalyticsModule extends FirebaseModule {
|
|
|
832
839
|
return Promise.resolve();
|
|
833
840
|
}
|
|
834
841
|
|
|
835
|
-
return
|
|
842
|
+
return (
|
|
843
|
+
this.native.initiateOnDeviceConversionMeasurementWithPhoneNumber?.(phoneNumber) ??
|
|
844
|
+
Promise.resolve()
|
|
845
|
+
);
|
|
836
846
|
}
|
|
837
847
|
|
|
838
848
|
initiateOnDeviceConversionMeasurementWithHashedPhoneNumber(
|
|
@@ -854,8 +864,9 @@ class FirebaseAnalyticsModule extends FirebaseModule {
|
|
|
854
864
|
return Promise.resolve();
|
|
855
865
|
}
|
|
856
866
|
|
|
857
|
-
return
|
|
858
|
-
hashedPhoneNumber
|
|
867
|
+
return (
|
|
868
|
+
this.native.initiateOnDeviceConversionMeasurementWithHashedPhoneNumber?.(hashedPhoneNumber) ??
|
|
869
|
+
Promise.resolve()
|
|
859
870
|
);
|
|
860
871
|
}
|
|
861
872
|
}
|
package/lib/structs.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { object, string, number, array, optional, define, type } from 'superstruct';
|
|
17
|
+
import { object, string, number, boolean, array, optional, define, type } from 'superstruct';
|
|
18
18
|
|
|
19
19
|
const ShortDate = define(
|
|
20
20
|
'ShortDate',
|
|
@@ -36,6 +36,7 @@ const Item = type({
|
|
|
36
36
|
item_variant: optional(string()),
|
|
37
37
|
quantity: optional(number()),
|
|
38
38
|
price: optional(number()),
|
|
39
|
+
index: optional(number()),
|
|
39
40
|
});
|
|
40
41
|
|
|
41
42
|
export const ScreenView = type({
|
|
@@ -104,7 +105,7 @@ export const JoinGroup = object({
|
|
|
104
105
|
|
|
105
106
|
export const LevelEnd = object({
|
|
106
107
|
level: number(),
|
|
107
|
-
success: optional(
|
|
108
|
+
success: optional(boolean()),
|
|
108
109
|
});
|
|
109
110
|
|
|
110
111
|
export const LevelStart = object({
|
package/lib/types/analytics.ts
CHANGED
|
@@ -282,7 +282,7 @@ export interface LevelEndEventParameters {
|
|
|
282
282
|
/**
|
|
283
283
|
* The result of an operation.
|
|
284
284
|
*/
|
|
285
|
-
success?:
|
|
285
|
+
success?: boolean;
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
export interface LevelStartEventParameters {
|
|
@@ -939,6 +939,7 @@ export interface Analytics extends ReactNativeFirebase.FirebaseModule {
|
|
|
939
939
|
logShare(object: ShareEventParameters): Promise<void>;
|
|
940
940
|
logSignUp(object: SignUpEventParameters): Promise<void>;
|
|
941
941
|
logSpendVirtualCurrency(object: SpendVirtualCurrencyEventParameters): Promise<void>;
|
|
942
|
+
logTransaction(transaction_id: string): Promise<void>;
|
|
942
943
|
logTutorialBegin(): Promise<void>;
|
|
943
944
|
logTutorialComplete(): Promise<void>;
|
|
944
945
|
logUnlockAchievement(object: UnlockAchievementEventParameters): Promise<void>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { Analytics } from './analytics';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Native Analytics module interface (RNFBAnalyticsModule).
|
|
22
|
+
* Matches the methods exposed by the native iOS/Android bridge.
|
|
23
|
+
* logTransaction and initiateOnDeviceConversionMeasurement* are iOS-only.
|
|
24
|
+
*/
|
|
25
|
+
export interface RNFBAnalyticsModule {
|
|
26
|
+
logEvent(name: string, params?: Record<string, unknown>): Promise<void>;
|
|
27
|
+
setUserId(userId: string | null): Promise<void>;
|
|
28
|
+
setUserProperty(key: string, value: string | null): Promise<void>;
|
|
29
|
+
setUserProperties(properties: Record<string, string | number | boolean | null>): Promise<void>;
|
|
30
|
+
setDefaultEventParameters(params?: Record<string, unknown> | null): Promise<void>;
|
|
31
|
+
setConsent(consent: Record<string, unknown>): Promise<void>;
|
|
32
|
+
setAnalyticsCollectionEnabled(enabled: boolean): Promise<void>;
|
|
33
|
+
resetAnalyticsData(): Promise<void>;
|
|
34
|
+
setSessionTimeoutDuration(milliseconds?: number): Promise<void>;
|
|
35
|
+
getAppInstanceId(): Promise<string | null>;
|
|
36
|
+
getSessionId(): Promise<number | null>;
|
|
37
|
+
/** iOS only (StoreKit 2). Not present on Android native. */
|
|
38
|
+
logTransaction(transactionId: string): Promise<void>;
|
|
39
|
+
/** iOS only. */
|
|
40
|
+
initiateOnDeviceConversionMeasurementWithEmailAddress?(emailAddress: string): Promise<void>;
|
|
41
|
+
/** iOS only. */
|
|
42
|
+
initiateOnDeviceConversionMeasurementWithHashedEmailAddress?(
|
|
43
|
+
hashedEmailAddress: string,
|
|
44
|
+
): Promise<void>;
|
|
45
|
+
/** iOS only. */
|
|
46
|
+
initiateOnDeviceConversionMeasurementWithPhoneNumber?(phoneNumber: string): Promise<void>;
|
|
47
|
+
/** iOS only. */
|
|
48
|
+
initiateOnDeviceConversionMeasurementWithHashedPhoneNumber?(
|
|
49
|
+
hashedPhoneNumber: string,
|
|
50
|
+
): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
declare module '@react-native-firebase/app/dist/module/internal/NativeModules' {
|
|
54
|
+
interface ReactNativeFirebaseNativeModules {
|
|
55
|
+
RNFBAnalyticsModule: RNFBAnalyticsModule;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Analytics instance with native module typed for modular API (e.g. logTransaction). */
|
|
60
|
+
export interface AnalyticsInternal extends Analytics {
|
|
61
|
+
readonly native: RNFBAnalyticsModule;
|
|
62
|
+
}
|
package/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '
|
|
2
|
+
export const version = '24.1.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-firebase/analytics",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "24.1.0",
|
|
4
4
|
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
|
|
5
5
|
"description": "React Native Firebase - The analytics module provides out of the box support with Google Analytics for Firebase. Integration with the Android & iOS allows for in-depth analytical insight reporting, such as device information, location, user actions and more.",
|
|
6
6
|
"main": "./dist/module/index.js",
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "genversion --esm --semi lib/version.ts",
|
|
10
10
|
"build:clean": "rimraf android/build && rimraf ios/build",
|
|
11
|
+
"build:plugin": "rimraf plugin/build && tsc --build plugin",
|
|
12
|
+
"lint:plugin": "eslint \"plugin/src/**/*.{ts,js}\"",
|
|
11
13
|
"compile": "bob build",
|
|
12
|
-
"prepare": "yarn run build && yarn compile"
|
|
14
|
+
"prepare": "yarn run build && yarn run build:plugin && yarn compile"
|
|
13
15
|
},
|
|
14
16
|
"repository": {
|
|
15
17
|
"type": "git",
|
|
@@ -23,7 +25,8 @@
|
|
|
23
25
|
"analytics"
|
|
24
26
|
],
|
|
25
27
|
"peerDependencies": {
|
|
26
|
-
"@react-native-firebase/app": "
|
|
28
|
+
"@react-native-firebase/app": "24.1.0",
|
|
29
|
+
"expo": ">=47.0.0"
|
|
27
30
|
},
|
|
28
31
|
"publishConfig": {
|
|
29
32
|
"access": "public",
|
|
@@ -33,7 +36,14 @@
|
|
|
33
36
|
"superstruct": "^2.0.2"
|
|
34
37
|
},
|
|
35
38
|
"devDependencies": {
|
|
36
|
-
"
|
|
39
|
+
"expo": "^55.0.5",
|
|
40
|
+
"react-native-builder-bob": "^0.40.17",
|
|
41
|
+
"typescript": "^5.9.3"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"expo": {
|
|
45
|
+
"optional": true
|
|
46
|
+
}
|
|
37
47
|
},
|
|
38
48
|
"exports": {
|
|
39
49
|
".": {
|
|
@@ -41,6 +51,7 @@
|
|
|
41
51
|
"types": "./dist/typescript/lib/index.d.ts",
|
|
42
52
|
"default": "./dist/module/index.js"
|
|
43
53
|
},
|
|
54
|
+
"./app.plugin.js": "./app.plugin.js",
|
|
44
55
|
"./package.json": "./package.json"
|
|
45
56
|
},
|
|
46
57
|
"react-native-builder-bob": {
|
|
@@ -65,5 +76,5 @@
|
|
|
65
76
|
"node_modules/",
|
|
66
77
|
"dist/"
|
|
67
78
|
],
|
|
68
|
-
"gitHead": "
|
|
79
|
+
"gitHead": "804a51fd265453f2385adb0ac96a6abf992c0316"
|
|
69
80
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
4
|
+
const ios_1 = require("./ios");
|
|
5
|
+
/**
|
|
6
|
+
* A config plugin for configuring `@react-native-firebase/analytics`
|
|
7
|
+
*/
|
|
8
|
+
const withRnFirebaseAnalytics = (config, props) => {
|
|
9
|
+
return (0, config_plugins_1.withPlugins)(config, [
|
|
10
|
+
// iOS
|
|
11
|
+
[ios_1.withIosWithoutAdIdSupport, props],
|
|
12
|
+
[ios_1.withIosGoogleAppMeasurementOnDeviceConversion, props],
|
|
13
|
+
]);
|
|
14
|
+
};
|
|
15
|
+
const pak = require('../../package.json');
|
|
16
|
+
exports.default = (0, config_plugins_1.createRunOncePlugin)(withRnFirebaseAnalytics, pak.name, pak.version);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withIosGoogleAppMeasurementOnDeviceConversion = exports.withIosWithoutAdIdSupport = void 0;
|
|
4
|
+
const podfile_1 = require("./podfile");
|
|
5
|
+
Object.defineProperty(exports, "withIosWithoutAdIdSupport", { enumerable: true, get: function () { return podfile_1.withIosWithoutAdIdSupport; } });
|
|
6
|
+
Object.defineProperty(exports, "withIosGoogleAppMeasurementOnDeviceConversion", { enumerable: true, get: function () { return podfile_1.withIosGoogleAppMeasurementOnDeviceConversion; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
+
import { PluginConfigType } from '../pluginConfig';
|
|
3
|
+
export declare function setAnalyticsPodfileWithoutAdIdSupport(src: string, enabled?: boolean): string;
|
|
4
|
+
export declare function setAnalyticsPodfileGoogleAppMeasurementOnDeviceConversion(src: string, enabled?: boolean): string;
|
|
5
|
+
export declare const withIosGoogleAppMeasurementOnDeviceConversion: ConfigPlugin<PluginConfigType>;
|
|
6
|
+
export declare const withIosWithoutAdIdSupport: ConfigPlugin<PluginConfigType>;
|