@umituz/react-native-auth 3.6.40 → 3.6.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-auth",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.42",
|
|
4
4
|
"description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -69,6 +69,9 @@ export interface UseAuthResult {
|
|
|
69
69
|
* Must call initializeAuthListener() once in app root.
|
|
70
70
|
*/
|
|
71
71
|
export function useAuth(): UseAuthResult {
|
|
72
|
+
if (typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
73
|
+
console.log('[useAuth] Hook called');
|
|
74
|
+
}
|
|
72
75
|
// State from store - using typed selectors
|
|
73
76
|
const user = useAuthStore(selectUser);
|
|
74
77
|
const loading = useAuthStore(selectLoading);
|
|
@@ -16,6 +16,10 @@ import type { AuthListenerOptions } from "../../types/auth-store.types";
|
|
|
16
16
|
declare const __DEV__: boolean;
|
|
17
17
|
|
|
18
18
|
let listenerInitialized = false;
|
|
19
|
+
// Reference counter for multiple subscribers
|
|
20
|
+
let listenerRefCount = 0;
|
|
21
|
+
// Actual unsubscribe function from Firebase
|
|
22
|
+
let firebaseUnsubscribe: (() => void) | null = null;
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* Initialize Firebase auth listener
|
|
@@ -33,11 +37,29 @@ export function initializeAuthListener(
|
|
|
33
37
|
});
|
|
34
38
|
}
|
|
35
39
|
|
|
40
|
+
// If already initialized, increment ref count and return unsubscribe that decrements
|
|
36
41
|
if (listenerInitialized) {
|
|
42
|
+
listenerRefCount++;
|
|
37
43
|
if (__DEV__) {
|
|
38
|
-
console.log("[AuthListener] Already initialized,
|
|
44
|
+
console.log("[AuthListener] Already initialized, incrementing ref count:", listenerRefCount);
|
|
39
45
|
}
|
|
40
|
-
|
|
46
|
+
// Return function that decrements ref count
|
|
47
|
+
return () => {
|
|
48
|
+
listenerRefCount--;
|
|
49
|
+
if (__DEV__) {
|
|
50
|
+
console.log("[AuthListener] Ref count decremented:", listenerRefCount);
|
|
51
|
+
}
|
|
52
|
+
// Only cleanup when all subscribers unsubscribe
|
|
53
|
+
if (listenerRefCount <= 0 && firebaseUnsubscribe) {
|
|
54
|
+
if (__DEV__) {
|
|
55
|
+
console.log("[AuthListener] Last subscriber, cleaning up");
|
|
56
|
+
}
|
|
57
|
+
firebaseUnsubscribe();
|
|
58
|
+
firebaseUnsubscribe = null;
|
|
59
|
+
listenerInitialized = false;
|
|
60
|
+
listenerRefCount = 0;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
41
63
|
}
|
|
42
64
|
|
|
43
65
|
const auth = getFirebaseAuth();
|
|
@@ -64,8 +86,9 @@ export function initializeAuthListener(
|
|
|
64
86
|
}
|
|
65
87
|
|
|
66
88
|
listenerInitialized = true;
|
|
89
|
+
listenerRefCount = 1;
|
|
67
90
|
|
|
68
|
-
|
|
91
|
+
firebaseUnsubscribe = onIdTokenChanged(auth, (user) => {
|
|
69
92
|
if (__DEV__) {
|
|
70
93
|
console.log("[AuthListener] onIdTokenChanged:", {
|
|
71
94
|
uid: user?.uid ?? null,
|
|
@@ -79,18 +102,40 @@ export function initializeAuthListener(
|
|
|
79
102
|
if (__DEV__) {
|
|
80
103
|
console.log("[AuthListener] No user, auto signing in anonymously...");
|
|
81
104
|
}
|
|
105
|
+
// Set loading state while attempting sign-in
|
|
106
|
+
store.setLoading(true);
|
|
107
|
+
|
|
82
108
|
void (async () => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
109
|
+
const MAX_RETRIES = 2;
|
|
110
|
+
const RETRY_DELAY_MS = 1000;
|
|
111
|
+
|
|
112
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
113
|
+
try {
|
|
114
|
+
await anonymousAuthService.signInAnonymously(auth);
|
|
115
|
+
if (__DEV__) {
|
|
116
|
+
console.log("[AuthListener] Anonymous sign-in successful");
|
|
117
|
+
}
|
|
118
|
+
// Success - the listener will fire again with the new user
|
|
119
|
+
return;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (__DEV__) {
|
|
122
|
+
console.warn(`[AuthListener] Anonymous sign-in attempt ${attempt + 1} failed:`, error);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// If not last attempt, wait and retry
|
|
126
|
+
if (attempt < MAX_RETRIES) {
|
|
127
|
+
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS));
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Last attempt failed - set error state
|
|
132
|
+
if (__DEV__) {
|
|
133
|
+
console.error("[AuthListener] All anonymous sign-in attempts failed");
|
|
134
|
+
}
|
|
135
|
+
store.setFirebaseUser(null);
|
|
136
|
+
store.setLoading(false);
|
|
137
|
+
store.setInitialized(true);
|
|
87
138
|
}
|
|
88
|
-
} catch (error) {
|
|
89
|
-
if (__DEV__) {
|
|
90
|
-
console.warn("[AuthListener] Anonymous sign-in failed:", error);
|
|
91
|
-
}
|
|
92
|
-
store.setFirebaseUser(null);
|
|
93
|
-
store.setInitialized(true);
|
|
94
139
|
}
|
|
95
140
|
})();
|
|
96
141
|
return;
|
|
@@ -110,11 +155,20 @@ export function initializeAuthListener(
|
|
|
110
155
|
});
|
|
111
156
|
|
|
112
157
|
return () => {
|
|
158
|
+
listenerRefCount--;
|
|
113
159
|
if (__DEV__) {
|
|
114
|
-
console.log("[AuthListener] Unsubscribing");
|
|
160
|
+
console.log("[AuthListener] Unsubscribing, ref count:", listenerRefCount);
|
|
161
|
+
}
|
|
162
|
+
// Only cleanup when all subscribers unsubscribe
|
|
163
|
+
if (listenerRefCount <= 0 && firebaseUnsubscribe) {
|
|
164
|
+
if (__DEV__) {
|
|
165
|
+
console.log("[AuthListener] Last subscriber, cleaning up listener");
|
|
166
|
+
}
|
|
167
|
+
firebaseUnsubscribe();
|
|
168
|
+
firebaseUnsubscribe = null;
|
|
169
|
+
listenerInitialized = false;
|
|
170
|
+
listenerRefCount = 0;
|
|
115
171
|
}
|
|
116
|
-
unsubscribe();
|
|
117
|
-
listenerInitialized = false;
|
|
118
172
|
};
|
|
119
173
|
}
|
|
120
174
|
|
|
@@ -122,7 +176,12 @@ export function initializeAuthListener(
|
|
|
122
176
|
* Reset listener state (for testing)
|
|
123
177
|
*/
|
|
124
178
|
export function resetAuthListener(): void {
|
|
179
|
+
if (firebaseUnsubscribe) {
|
|
180
|
+
firebaseUnsubscribe();
|
|
181
|
+
firebaseUnsubscribe = null;
|
|
182
|
+
}
|
|
125
183
|
listenerInitialized = false;
|
|
184
|
+
listenerRefCount = 0;
|
|
126
185
|
}
|
|
127
186
|
|
|
128
187
|
/**
|