Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: events not being sent when adTrackingEnabled is false #1024

Merged
merged 9 commits into from
Nov 14, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,47 @@ class AnalyticsReactNativePluginAdvertisingIdModule(reactContext: ReactApplicati
return "AnalyticsReactNativePluginAdvertisingId"
}

@ReactMethod
@ReactMethod
fun getAdvertisingId(promise: Promise) {
if (currentActivity?.application == null) {
promise.resolve(null)
return
}

val reactContext = (currentActivity?.application as ReactApplication)
?.reactNativeHost
?.reactInstanceManager
?.currentReactContext

if (reactContext == null) {
promise.resolve(null)
return
}

try {
val advertisingInfo = AdvertisingIdClient.getAdvertisingIdInfo(reactContext)
val isLimitAdTrackingEnabled = advertisingInfo.isLimitAdTrackingEnabled

if (isLimitAdTrackingEnabled) {
promise.resolve(null)
}

val id = advertisingInfo.id
val advertisingId = id.toString()
promise.resolve(advertisingId)
}
catch (e: GooglePlayServicesNotAvailableException) {
Log.d(name, e.toString())
promise.resolve(null)
}
catch ( e: IOException) {
Log.d(name, e.toString())
promise.resolve(null)
}
getAdvertisingIdInfo(promise) { advertisingInfo ->
val id = advertisingInfo.id
promise.resolve(id.toString())
}
}

@ReactMethod
fun getIsLimitAdTrackingEnableStatus(promise: Promise) {
getAdvertisingIdInfo(promise) { advertisingInfo ->
val isLimitAdTrackingEnabled = advertisingInfo.isLimitAdTrackingEnabled
promise.resolve(isLimitAdTrackingEnabled)
}
}

private fun getAdvertisingIdInfo(promise: Promise, callback: (AdvertisingIdClient.Info) -> Unit) {
if (currentActivity?.application == null) {
promise.resolve(null)
return
}

val reactContext = (currentActivity?.application as ReactApplication)
?.reactNativeHost
?.reactInstanceManager
?.currentReactContext

if (reactContext == null) {
promise.resolve(null)
return
}

try {
val advertisingInfo = AdvertisingIdClient.getAdvertisingIdInfo(reactContext)
callback(advertisingInfo)
} catch (e: GooglePlayServicesNotAvailableException) {
Log.d(name, e.toString())
promise.resolve(null)
} catch (e: IOException) {
Log.d(name, e.toString())
promise.resolve(null)
}
}
}
77 changes: 52 additions & 25 deletions packages/plugins/plugin-advertising-id/src/AdvertisingIdPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,69 +5,70 @@ import {
getNativeModule,
ErrorType,
SegmentError,
SegmentEvent
SegmentEvent,
} from '@segment/analytics-react-native';

import { Platform, NativeModule } from 'react-native';

type AdvertisingIDNativeModule = NativeModule & {
getAdvertisingId: () => Promise<string>;
getIsLimitAdTrackingEnableStatus: () => Promise<boolean>;
};

export class AdvertisingIdPlugin extends Plugin {
type = PluginType.enrichment;
queuedEvents: SegmentEvent[] = [];
advertisingId?: string = undefined;
isLimitAdTracking?: boolean = false;

configure(analytics: SegmentClient): void {
if (Platform.OS !== 'android') {
return;
}

this.analytics = analytics;
(
getNativeModule(
'AnalyticsReactNativePluginAdvertisingId'
) as AdvertisingIDNativeModule
)
?.getAdvertisingId()
.then((id: string) => {
// Create an array of promises for fetching advertising ID and limit ad tracking status
const advertisingIdPromise = this.fetchAdvertisingId();
const limitAdTrackingStatusPromise = this.fetchLimitAdTrackingStatus();
// Wait for both promises to resolve
Promise.all([advertisingIdPromise, limitAdTrackingStatusPromise])
.then(([id, status]) => {
//handle advertisingID
if (id === null) {
// Need to check this condition
void analytics.track(
'LimitAdTrackingEnabled (Google Play Services) is enabled'
);
} else {
this.advertisingId = id
void this.setContext(id);
this.advertisingId = id;
}
//handle isLimitAdTrackingEnableStatus
this.isLimitAdTracking = status;

// Call setContext after both values are available
void this.setContext(this.advertisingId, status);
})
.catch((error) => {
this.analytics?.reportInternalError(
new SegmentError(
ErrorType.PluginError,
'Error retrieving AdvertisingID',
error
)
);
});
.catch((error) => this.handleError(error));
}

execute(event: SegmentEvent){

execute(event: SegmentEvent) {
if (this.advertisingId === undefined) {
this.queuedEvents.push(event);
}else{
} else {
return event;
}
return;
}

async setContext(id: string): Promise<void> {
async setContext(
id: string | undefined,
isLimitAdTrackingEnableStatus: boolean
): Promise<void> {
try {
await this.analytics?.context.set({
device: {
advertisingId: id,
adTrackingEnabled: true,
adTrackingEnabled: !isLimitAdTrackingEnableStatus,
},
});
this.sendQueued();
Expand All @@ -81,9 +82,35 @@ export class AdvertisingIdPlugin extends Plugin {
}

sendQueued() {
this.queuedEvents.forEach(event => {
this.queuedEvents.forEach((event) => {
void this.analytics?.process(event);
});
this.queuedEvents = [];
}

private fetchAdvertisingId(): Promise<string | null> {
return (
getNativeModule(
'AnalyticsReactNativePluginAdvertisingId'
) as AdvertisingIDNativeModule
)?.getAdvertisingId();
}

private fetchLimitAdTrackingStatus(): Promise<boolean> {
return (
getNativeModule(
'AnalyticsReactNativePluginAdvertisingId'
) as AdvertisingIDNativeModule
)?.getIsLimitAdTrackingEnableStatus();
}

private handleError(error: unknown): void {
this.analytics?.reportInternalError(
new SegmentError(
ErrorType.PluginError,
'Error retrieving AdvertisingID',
error
)
);
}
}
Loading