1- import { useEffect , useState } from "react" ;
1+ import { useEffect , useRef , useState } from "react" ;
22import { useSession } from '@/providers/SessionProvider' ;
33import * as LocationLibrary from "expo-location" ;
44import {
@@ -17,11 +17,11 @@ export const useLocation = (fcmToken: string | null) => {
1717 const [ error , setError ] = useState < string | null > ( null ) ;
1818 const [ loading , setLoading ] = useState < boolean > ( false ) ;
1919
20- const fetchLocation = async ( ) => {
20+ const fetchLocation = async ( tokenForSave : string | null ) => {
2121 try {
2222 setLoading ( true ) ;
2323
24- if ( ! fcmToken ) {
24+ if ( ! tokenForSave ) {
2525 console . log (
2626 "fetchLocation invoked without an FCM token; aborting location save step."
2727 ) ;
@@ -43,7 +43,7 @@ export const useLocation = (fcmToken: string | null) => {
4343 setAddress ( geoAddress ) ;
4444
4545 if ( geoAddress ) {
46- await saveLocation ( currentLocation , geoAddress , fcmToken ) ; // Pass fcmToken (may be null; saveLocation will re-check)
46+ await saveLocation ( currentLocation , geoAddress , tokenForSave ) ; // Pass resolved token (may be null; saveLocation will re-check)
4747 } else {
4848 console . log ( "Geo address unavailable; skipping saveLocation." ) ;
4949 }
@@ -58,12 +58,26 @@ export const useLocation = (fcmToken: string | null) => {
5858
5959 const { waitForFcmToken } = useSession ( ) ;
6060
61+ const lastSavedTokenRef = useRef < string | null > ( null ) ;
62+ const inFlightRef = useRef ( false ) ;
63+
6164 useEffect ( ( ) => {
6265 let cancelled = false ;
6366 ( async ( ) => {
6467 const token = fcmToken || ( await waitForFcmToken ( ) ) ;
65- if ( ! cancelled && token ) {
66- fetchLocation ( ) ;
68+ if ( cancelled || ! token ) return ;
69+
70+ // React 18 StrictMode and token updates can cause this effect to run twice.
71+ // Only save once per token (and avoid overlapping requests).
72+ if ( inFlightRef . current ) return ;
73+ if ( lastSavedTokenRef . current === token ) return ;
74+
75+ inFlightRef . current = true ;
76+ try {
77+ await fetchLocation ( token ) ;
78+ lastSavedTokenRef . current = token ;
79+ } finally {
80+ inFlightRef . current = false ;
6781 }
6882 } ) ( ) ;
6983 return ( ) => {
0 commit comments