@@ -313,14 +313,37 @@ export namespace OneSignal {
313313 return pushSub . id ? pushSub . id : '' ;
314314 }
315315
316- export async function getIdAsync ( ) : Promise < string | null > {
316+ /**
317+ * Gets the push subscription ID, waiting for it to be available if necessary.
318+ *
319+ * This method addresses a race condition where the subscription ID may not be
320+ * immediately available after permission is granted. It uses native event
321+ * listeners to wait for the ID to be generated, with a configurable timeout.
322+ *
323+ * @param options - Optional configuration
324+ * @param options.timeout - Maximum time to wait in milliseconds (default: 5000)
325+ * @returns The subscription ID, or null if not available after timeout
326+ */
327+ export async function getIdAsync ( options ?: {
328+ timeout ?: number ;
329+ } ) : Promise < string | null > {
317330 if ( ! isNativeModuleLoaded ( RNOneSignal ) ) {
318331 return Promise . reject (
319332 new Error ( 'OneSignal native module not loaded' ) ,
320333 ) ;
321334 }
322335
323- return await RNOneSignal . getPushSubscriptionId ( ) ;
336+ const timeout = options ?. timeout ?? 5000 ;
337+
338+ // Use the native wait method which listens for subscription events
339+ const id = await RNOneSignal . waitForPushSubscriptionIdAsync ( timeout ) ;
340+
341+ // Update cached state if we got an ID
342+ if ( id ) {
343+ pushSub . id = id ;
344+ }
345+
346+ return id ;
324347 }
325348
326349 /**
@@ -337,15 +360,39 @@ export namespace OneSignal {
337360 return pushSub . token ? pushSub . token : '' ;
338361 }
339362
340- /** The readonly push subscription token */
341- export async function getTokenAsync ( ) : Promise < string | null > {
363+ /**
364+ * Gets the push subscription token, waiting for it to be available if necessary.
365+ *
366+ * This method addresses a race condition where the subscription token may not be
367+ * immediately available after permission is granted. It uses native event
368+ * listeners to wait for the token to be generated, with a configurable timeout.
369+ *
370+ * @param options - Optional configuration
371+ * @param options.timeout - Maximum time to wait in milliseconds (default: 5000)
372+ * @returns The subscription token, or null if not available after timeout
373+ */
374+ export async function getTokenAsync ( options ?: {
375+ timeout ?: number ;
376+ } ) : Promise < string | null > {
342377 if ( ! isNativeModuleLoaded ( RNOneSignal ) ) {
343378 return Promise . reject (
344379 new Error ( 'OneSignal native module not loaded' ) ,
345380 ) ;
346381 }
347382
348- return await RNOneSignal . getPushSubscriptionToken ( ) ;
383+ const timeout = options ?. timeout ?? 5000 ;
384+
385+ // Use the native wait method which listens for subscription events
386+ const token = await RNOneSignal . waitForPushSubscriptionTokenAsync (
387+ timeout ,
388+ ) ;
389+
390+ // Update cached state if we got a token
391+ if ( token ) {
392+ pushSub . token = token ;
393+ }
394+
395+ return token ;
349396 }
350397
351398 /**
0 commit comments