diff --git a/examples/demo/src/hooks/useOneSignal.ts b/examples/demo/src/hooks/useOneSignal.ts index bd1359c0..5587c2af 100644 --- a/examples/demo/src/hooks/useOneSignal.ts +++ b/examples/demo/src/hooks/useOneSignal.ts @@ -19,6 +19,7 @@ import { type InAppMessageWillDisplayEvent, type NotificationClickEvent, type NotificationWillDisplayEvent, + type PushSubscriptionChangedState, type UserChangedState, } from 'react-native-onesignal'; @@ -139,10 +140,10 @@ function useOneSignalState(): UseOneSignalReturn { try { const onesignalId = await OneSignal.User.getOnesignalId(); - if (!onesignalId) return; + if (!onesignalId || requestSequenceRef.current !== requestId) return; const userData = await apiService.fetchUser(onesignalId); - if (!userData) return; + if (!userData || requestSequenceRef.current !== requestId) return; const externalId = await OneSignal.User.getExternalId(); @@ -153,6 +154,8 @@ function useOneSignalState(): UseOneSignalReturn { setEmailsList((prev) => mergeUnique(prev, userData.emails)); setSmsNumbersList((prev) => mergeUnique(prev, userData.smsNumbers)); setExternalUserId(externalId ?? userData.externalId); + } catch (err) { + console.error(`Fetch user error: ${String(err)}`); } finally { if (requestSequenceRef.current === requestId) { setIsLoading(false); @@ -161,6 +164,11 @@ function useOneSignalState(): UseOneSignalReturn { }, []); useEffect(() => { + let cancelled = false; + let pushChanged = false; + let permissionChanged = false; + let userChanged = false; + const handleIamWillDisplay = (e: InAppMessageWillDisplayEvent) => { console.log(`IAM willDisplay: ${e.message.messageId}`); }; @@ -190,28 +198,30 @@ function useOneSignalState(): UseOneSignalReturn { e.getNotification().display(); }; - const pushSubHandler = async () => { - const [id, optedIn] = await Promise.all([ - OneSignal.User.pushSubscription.getIdAsync(), - OneSignal.User.pushSubscription.getOptedInAsync(), - ]); - setPushSubscriptionId(id ?? undefined); - setIsPushEnabled(optedIn); + const pushSubHandler = (event: PushSubscriptionChangedState) => { + pushChanged = true; + setPushSubscriptionId(event.current.id ?? undefined); + setIsPushEnabled(event.current.optedIn); }; const permissionHandler = (granted: boolean) => { + permissionChanged = true; setHasNotificationPermission(granted); }; const userChangeHandler = (event: UserChangedState) => { + userChanged = true; + requestSequenceRef.current++; const nextOnesignalId = event.current.onesignalId ?? null; console.log( `User changed: onesignalId=${nextOnesignalId ?? 'null'}, externalId=${event.current.externalId ?? 'null'}`, ); setOneSignalId(nextOnesignalId ?? undefined); + setExternalUserId(event.current.externalId ?? undefined); if (nextOnesignalId === null) { + setIsLoading(false); return; } @@ -228,6 +238,7 @@ function useOneSignalState(): UseOneSignalReturn { preferences.getLocationShared(), ]); const storedExternalUserId = (await preferences.getExternalUserId()) ?? undefined; + if (cancelled) return; apiService.setAppId(nextAppId); @@ -265,37 +276,43 @@ function useOneSignalState(): UseOneSignalReturn { console.log(`OneSignal initialized with app ID: ${nextAppId}`); - const externalId = await OneSignal.User.getExternalId(); - const [pushId, pushOptedIn, hasPerm] = await Promise.all([ + const [externalId, initialOnesignalId, pushId, pushOptedIn, hasPerm] = await Promise.all([ + OneSignal.User.getExternalId(), + OneSignal.User.getOnesignalId(), OneSignal.User.pushSubscription.getIdAsync(), OneSignal.User.pushSubscription.getOptedInAsync(), OneSignal.Notifications.getPermissionAsync(), ]); + if (cancelled) return; setAppId(nextAppId); setConsentRequiredState(nextConsentRequired); setPrivacyConsentGivenState(nextPrivacyConsentGiven); setInAppMessagesPaused(nextIamPaused); setLocationSharedState(nextLocationShared); - setExternalUserId(externalId ?? storedExternalUserId); - setPushSubscriptionId(pushId ?? undefined); - setIsPushEnabled(pushOptedIn); - setHasNotificationPermission(hasPerm); + if (!pushChanged) { + setPushSubscriptionId(pushId ?? undefined); + setIsPushEnabled(pushOptedIn); + } + if (!permissionChanged) setHasNotificationPermission(hasPerm); setIsReady(true); - const initialOnesignalId = await OneSignal.User.getOnesignalId(); - setOneSignalId(initialOnesignalId ?? undefined); - if (initialOnesignalId) { - await fetchUserDataFromApi(); + if (!userChanged) { + setExternalUserId(externalId ?? storedExternalUserId); + setOneSignalId(initialOnesignalId ?? undefined); + if (initialOnesignalId) await fetchUserDataFromApi(); } }; void load().catch((err) => { + if (cancelled) return; console.error(`Initial load error: ${String(err)}`); setIsLoading(false); }); return () => { + cancelled = true; + requestSequenceRef.current++; OneSignal.InAppMessages.removeEventListener('willDisplay', handleIamWillDisplay); OneSignal.InAppMessages.removeEventListener('didDisplay', handleIamDidDisplay); OneSignal.InAppMessages.removeEventListener('willDismiss', handleIamWillDismiss); @@ -313,6 +330,7 @@ function useOneSignalState(): UseOneSignalReturn { }, [fetchUserDataFromApi]); const loginUser = async (nextExternalUserId: string) => { + requestSequenceRef.current++; setAliasesList([]); setEmailsList([]); setSmsNumbersList([]); @@ -334,6 +352,8 @@ function useOneSignalState(): UseOneSignalReturn { }; const logoutUser = async () => { + requestSequenceRef.current++; + setIsLoading(false); OneSignal.logout(); await preferences.setExternalUserId(null); setExternalUserId(undefined);