Skip to content

Commit

Permalink
fix: Android Advertising ID does not update unless app is relaunched (#…
Browse files Browse the repository at this point in the history
…1033)

* fix: to show 'Queue restoration timeout' only once

* fix: advertising id being sent for Android application installed events

* chore: add privacy manifest file to core package

* fix: events not being sent when adTrackingEnabled is false

* fix: type mismatch inferred type is String? but String was expected

* Revert "fix: type mismatch inferred type is String? but String was expected"

This reverts commit 2b1e1fc.

* chore: upgrade AnalyticsReactNativeExample to RN 0.76

* chore: upgrade AnalyticsReactNativeExample RN version to 0.76

* chore: removed actual write key with placeholder after testing

* fix: Android Advertising ID does not update unless app is relaunched

---------

Co-authored-by: Sunita Prajapati <>
  • Loading branch information
thesunita authored Dec 16, 2024
1 parent bde0ebb commit 53ee59d
Showing 1 changed file with 70 additions and 25 deletions.
95 changes: 70 additions & 25 deletions packages/plugins/plugin-advertising-id/src/AdvertisingIdPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
ErrorType,
SegmentError,
SegmentEvent,
EventType,
TrackEventType,
} from '@segment/analytics-react-native';

import { Platform, NativeModule } from 'react-native';
Expand All @@ -18,48 +20,91 @@ type AdvertisingIDNativeModule = NativeModule & {
export class AdvertisingIdPlugin extends Plugin {
type = PluginType.enrichment;
queuedEvents: SegmentEvent[] = [];
advertisingId?: string = undefined;
isLimitAdTracking?: boolean = false;
advertisingId: string | undefined | null = undefined;
isLimitAdTracking?: boolean = undefined;

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

this.analytics = analytics;
// 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;
}
//handle isLimitAdTrackingEnableStatus
this.isLimitAdTracking = status;

// Call setContext after both values are available
void this.setContext(this.advertisingId, status);
this.fetchAdvertisingInfo()
.then(() => {
// Additional logic after the advertising info is fetched
this.sendQueued();
})
.catch((error) => this.handleError(error));
.catch((error) => {
this.handleError(error);
});
}

execute(event: SegmentEvent) {
async execute(event: SegmentEvent) {
// If advertisingId is not set, queue the event
if (this.advertisingId === undefined) {
this.queuedEvents.push(event);
} else {
// Send event if advertisingId is available
const currentLimitAdTrackingStatus =
await this.fetchLimitAdTrackingStatus();
if (this.isLimitAdTracking === undefined) {
this.isLimitAdTracking = currentLimitAdTrackingStatus;
} else if (this.isLimitAdTracking !== currentLimitAdTrackingStatus) {
//Fetch the fresh advertising id
await this.fetchAdvertisingInfo()
.then(() => {
console.log(
'Advertising info fetched successfully when adTrackingStatus Changed.'
);
// Additional logic after the advertising info is fetched
})
.catch((error) => {
this.handleError(error);
});
this.queuedEvents.push(event);
this.isLimitAdTracking = currentLimitAdTrackingStatus;
this.sendQueued();
return;
}
return event;
}

return;
}

isTrackEvent(event: SegmentEvent): event is TrackEventType {
return event.type === EventType.TrackEvent;
}

private async fetchAdvertisingInfo(): Promise<void> {
const advertisingIdPromise = this.fetchAdvertisingId();
const limitAdTrackingStatusPromise = this.fetchLimitAdTrackingStatus();

try {
// Await both promises to resolve simultaneously
const [id, status] = await Promise.all([
advertisingIdPromise,
limitAdTrackingStatusPromise,
]);

// Handle advertisingID
if (id === null) {
void this.analytics?.track(
'LimitAdTrackingEnabled (Google Play Services) is enabled'
);
this.advertisingId = undefined; // Set to undefined if id is null
} else {
this.advertisingId = id;
}

// Set context after both values are available
await this.setContext(id as string, status);
} catch (error) {
this.handleError(error);
}
}

async setContext(
id: string | undefined,
isLimitAdTrackingEnableStatus: boolean
Expand All @@ -71,7 +116,6 @@ export class AdvertisingIdPlugin extends Plugin {
adTrackingEnabled: !isLimitAdTrackingEnableStatus,
},
});
this.sendQueued();
} catch (error) {
const message = 'AdvertisingID failed to set context';
this.analytics?.reportInternalError(
Expand All @@ -82,6 +126,7 @@ export class AdvertisingIdPlugin extends Plugin {
}

sendQueued() {
console.log('Sending queued events:', this.queuedEvents);
this.queuedEvents.forEach((event) => {
void this.analytics?.process(event);
});
Expand Down

0 comments on commit 53ee59d

Please sign in to comment.