@blackcode_sa/metaestetics-api 1.14.16 → 1.14.18
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/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +89 -3
- package/dist/index.mjs +89 -3
- package/package.json +1 -1
- package/src/services/auth/auth.service.ts +121 -0
package/dist/index.d.mts
CHANGED
|
@@ -8321,6 +8321,23 @@ declare class AuthService extends BaseService {
|
|
|
8321
8321
|
private googleProvider;
|
|
8322
8322
|
private userService;
|
|
8323
8323
|
constructor(db: Firestore, auth: Auth, app: FirebaseApp, userService: UserService);
|
|
8324
|
+
/**
|
|
8325
|
+
* Waits for Firebase Auth state to settle after sign-in.
|
|
8326
|
+
*
|
|
8327
|
+
* In React Native with AsyncStorage persistence, there's a critical issue:
|
|
8328
|
+
* 1. signInWithCredential() sets auth.currentUser in memory immediately
|
|
8329
|
+
* 2. But AsyncStorage persistence happens asynchronously
|
|
8330
|
+
* 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
|
|
8331
|
+
* 4. This causes auth.currentUser to become NULL even after it was set
|
|
8332
|
+
*
|
|
8333
|
+
* This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
|
|
8334
|
+
* It ensures the auth state persists through AsyncStorage operations.
|
|
8335
|
+
*
|
|
8336
|
+
* @param expectedUid - The UID we expect to see in auth.currentUser
|
|
8337
|
+
* @param timeoutMs - Maximum time to wait (default 5 seconds)
|
|
8338
|
+
* @returns Promise that resolves when auth state is ready and stable
|
|
8339
|
+
*/
|
|
8340
|
+
private waitForAuthStateToSettle;
|
|
8324
8341
|
/**
|
|
8325
8342
|
* Registruje novog korisnika sa email-om i lozinkom
|
|
8326
8343
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -8321,6 +8321,23 @@ declare class AuthService extends BaseService {
|
|
|
8321
8321
|
private googleProvider;
|
|
8322
8322
|
private userService;
|
|
8323
8323
|
constructor(db: Firestore, auth: Auth, app: FirebaseApp, userService: UserService);
|
|
8324
|
+
/**
|
|
8325
|
+
* Waits for Firebase Auth state to settle after sign-in.
|
|
8326
|
+
*
|
|
8327
|
+
* In React Native with AsyncStorage persistence, there's a critical issue:
|
|
8328
|
+
* 1. signInWithCredential() sets auth.currentUser in memory immediately
|
|
8329
|
+
* 2. But AsyncStorage persistence happens asynchronously
|
|
8330
|
+
* 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
|
|
8331
|
+
* 4. This causes auth.currentUser to become NULL even after it was set
|
|
8332
|
+
*
|
|
8333
|
+
* This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
|
|
8334
|
+
* It ensures the auth state persists through AsyncStorage operations.
|
|
8335
|
+
*
|
|
8336
|
+
* @param expectedUid - The UID we expect to see in auth.currentUser
|
|
8337
|
+
* @param timeoutMs - Maximum time to wait (default 5 seconds)
|
|
8338
|
+
* @returns Promise that resolves when auth state is ready and stable
|
|
8339
|
+
*/
|
|
8340
|
+
private waitForAuthStateToSettle;
|
|
8324
8341
|
/**
|
|
8325
8342
|
* Registruje novog korisnika sa email-om i lozinkom
|
|
8326
8343
|
*/
|
package/dist/index.js
CHANGED
|
@@ -15402,6 +15402,73 @@ ${stackTrace}`);
|
|
|
15402
15402
|
console.log("[AUTH] AuthService initialized");
|
|
15403
15403
|
console.log("[AUTH] Initial auth.currentUser:", ((_a = this.auth.currentUser) == null ? void 0 : _a.uid) || "NULL");
|
|
15404
15404
|
}
|
|
15405
|
+
/**
|
|
15406
|
+
* Waits for Firebase Auth state to settle after sign-in.
|
|
15407
|
+
*
|
|
15408
|
+
* In React Native with AsyncStorage persistence, there's a critical issue:
|
|
15409
|
+
* 1. signInWithCredential() sets auth.currentUser in memory immediately
|
|
15410
|
+
* 2. But AsyncStorage persistence happens asynchronously
|
|
15411
|
+
* 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
|
|
15412
|
+
* 4. This causes auth.currentUser to become NULL even after it was set
|
|
15413
|
+
*
|
|
15414
|
+
* This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
|
|
15415
|
+
* It ensures the auth state persists through AsyncStorage operations.
|
|
15416
|
+
*
|
|
15417
|
+
* @param expectedUid - The UID we expect to see in auth.currentUser
|
|
15418
|
+
* @param timeoutMs - Maximum time to wait (default 5 seconds)
|
|
15419
|
+
* @returns Promise that resolves when auth state is ready and stable
|
|
15420
|
+
*/
|
|
15421
|
+
async waitForAuthStateToSettle(expectedUid, timeoutMs = 5e3) {
|
|
15422
|
+
var _a, _b, _c;
|
|
15423
|
+
if (((_a = this.auth.currentUser) == null ? void 0 : _a.uid) === expectedUid) {
|
|
15424
|
+
console.log("[AUTH] Auth state appears set, waiting for stability...");
|
|
15425
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
15426
|
+
if (((_b = this.auth.currentUser) == null ? void 0 : _b.uid) === expectedUid) {
|
|
15427
|
+
console.log("[AUTH] \u2705 Auth state stable for:", expectedUid);
|
|
15428
|
+
return;
|
|
15429
|
+
}
|
|
15430
|
+
}
|
|
15431
|
+
console.log("[AUTH] Waiting for auth state to settle for:", expectedUid);
|
|
15432
|
+
console.log("[AUTH] Current auth.currentUser:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
|
|
15433
|
+
return new Promise((resolve, reject) => {
|
|
15434
|
+
const startTime = Date.now();
|
|
15435
|
+
let resolved = false;
|
|
15436
|
+
const unsubscribe = (0, import_auth8.onAuthStateChanged)(this.auth, (user) => {
|
|
15437
|
+
if (resolved) return;
|
|
15438
|
+
const currentUid = (user == null ? void 0 : user.uid) || null;
|
|
15439
|
+
console.log("[AUTH] onAuthStateChanged fired:", currentUid || "NULL");
|
|
15440
|
+
if (currentUid === expectedUid) {
|
|
15441
|
+
setTimeout(() => {
|
|
15442
|
+
var _a2;
|
|
15443
|
+
if (resolved) return;
|
|
15444
|
+
if (((_a2 = this.auth.currentUser) == null ? void 0 : _a2.uid) === expectedUid) {
|
|
15445
|
+
resolved = true;
|
|
15446
|
+
unsubscribe();
|
|
15447
|
+
clearTimeout(timeout);
|
|
15448
|
+
const elapsed = Date.now() - startTime;
|
|
15449
|
+
console.log(`[AUTH] \u2705 Auth state settled and stable after ${elapsed}ms for:`, expectedUid);
|
|
15450
|
+
resolve();
|
|
15451
|
+
} else {
|
|
15452
|
+
console.warn("[AUTH] \u26A0\uFE0F Auth state became NULL after being set, waiting more...");
|
|
15453
|
+
}
|
|
15454
|
+
}, 300);
|
|
15455
|
+
} else if (currentUid === null && Date.now() - startTime > 1e3) {
|
|
15456
|
+
console.error("[AUTH] \u274C Auth state became NULL after being set!");
|
|
15457
|
+
console.error("[AUTH] This indicates AsyncStorage persistence issue");
|
|
15458
|
+
}
|
|
15459
|
+
});
|
|
15460
|
+
const timeout = setTimeout(() => {
|
|
15461
|
+
var _a2, _b2;
|
|
15462
|
+
if (resolved) return;
|
|
15463
|
+
resolved = true;
|
|
15464
|
+
unsubscribe();
|
|
15465
|
+
console.error("[AUTH] \u274C Timeout waiting for auth state to settle");
|
|
15466
|
+
console.error("[AUTH] Expected UID:", expectedUid);
|
|
15467
|
+
console.error("[AUTH] Actual auth.currentUser:", ((_a2 = this.auth.currentUser) == null ? void 0 : _a2.uid) || "NULL");
|
|
15468
|
+
reject(new Error(`Timeout waiting for auth state to settle. Expected: ${expectedUid}, Got: ${((_b2 = this.auth.currentUser) == null ? void 0 : _b2.uid) || "NULL"}`));
|
|
15469
|
+
}, timeoutMs);
|
|
15470
|
+
});
|
|
15471
|
+
}
|
|
15405
15472
|
/**
|
|
15406
15473
|
* Registruje novog korisnika sa email-om i lozinkom
|
|
15407
15474
|
*/
|
|
@@ -16154,6 +16221,9 @@ ${stackTrace}`);
|
|
|
16154
16221
|
const credential = import_auth8.GoogleAuthProvider.credential(idToken);
|
|
16155
16222
|
const { user: firebaseUser } = await (0, import_auth8.signInWithCredential)(this.auth, credential);
|
|
16156
16223
|
console.log("[AUTH] Firebase user signed in:", firebaseUser.uid);
|
|
16224
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16225
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
16226
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16157
16227
|
const existingUser = await this.userService.getUserById(firebaseUser.uid);
|
|
16158
16228
|
if (existingUser) {
|
|
16159
16229
|
console.log("[AUTH] Existing user found, returning profile:", existingUser.uid);
|
|
@@ -16179,7 +16249,7 @@ ${stackTrace}`);
|
|
|
16179
16249
|
* @returns Object containing user, practitioner (if exists), and draft profiles (if any)
|
|
16180
16250
|
*/
|
|
16181
16251
|
async signUpPractitionerWithGoogle(idToken) {
|
|
16182
|
-
var _a, _b, _c;
|
|
16252
|
+
var _a, _b, _c, _d;
|
|
16183
16253
|
try {
|
|
16184
16254
|
console.log("[AUTH] Starting practitioner Google Sign-In/Sign-Up");
|
|
16185
16255
|
let email;
|
|
@@ -16213,6 +16283,9 @@ ${stackTrace}`);
|
|
|
16213
16283
|
console.log("[AUTH] User exists with Google provider, signing in");
|
|
16214
16284
|
const credential2 = import_auth8.GoogleAuthProvider.credential(idToken);
|
|
16215
16285
|
const { user: firebaseUser2 } = await (0, import_auth8.signInWithCredential)(this.auth, credential2);
|
|
16286
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16287
|
+
await this.waitForAuthStateToSettle(firebaseUser2.uid);
|
|
16288
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16216
16289
|
let existingUser2 = null;
|
|
16217
16290
|
try {
|
|
16218
16291
|
existingUser2 = await this.userService.getUserById(firebaseUser2.uid);
|
|
@@ -16224,6 +16297,16 @@ ${stackTrace}`);
|
|
|
16224
16297
|
errorType: (_a = userError == null ? void 0 : userError.constructor) == null ? void 0 : _a.name,
|
|
16225
16298
|
isAuthError: userError instanceof AuthError
|
|
16226
16299
|
});
|
|
16300
|
+
if (!this.auth.currentUser || this.auth.currentUser.uid !== firebaseUser2.uid) {
|
|
16301
|
+
console.error("[AUTH] \u274C auth.currentUser became NULL before draft profile query!");
|
|
16302
|
+
console.error("[AUTH] Expected UID:", firebaseUser2.uid);
|
|
16303
|
+
console.error("[AUTH] Actual auth.currentUser:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
|
|
16304
|
+
console.log("[AUTH] Re-signing in to restore auth state before query...");
|
|
16305
|
+
const credential3 = import_auth8.GoogleAuthProvider.credential(idToken);
|
|
16306
|
+
await (0, import_auth8.signInWithCredential)(this.auth, credential3);
|
|
16307
|
+
await this.waitForAuthStateToSettle(firebaseUser2.uid, 2e3);
|
|
16308
|
+
console.log("[AUTH] \u2705 Auth state restored, proceeding with query");
|
|
16309
|
+
}
|
|
16227
16310
|
const practitionerService2 = new PractitionerService(this.db, this.auth, this.app);
|
|
16228
16311
|
const draftProfiles3 = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
|
|
16229
16312
|
console.log("[AUTH] Draft profiles check result:", {
|
|
@@ -16245,7 +16328,7 @@ ${stackTrace}`);
|
|
|
16245
16328
|
);
|
|
16246
16329
|
}
|
|
16247
16330
|
console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
|
|
16248
|
-
console.log("[AUTH] auth.currentUser at User creation time:", ((
|
|
16331
|
+
console.log("[AUTH] auth.currentUser at User creation time:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
|
|
16249
16332
|
try {
|
|
16250
16333
|
const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
|
|
16251
16334
|
skipProfileCreation: true
|
|
@@ -16313,6 +16396,9 @@ ${stackTrace}`);
|
|
|
16313
16396
|
}
|
|
16314
16397
|
throw error;
|
|
16315
16398
|
}
|
|
16399
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16400
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
16401
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16316
16402
|
let existingUser = null;
|
|
16317
16403
|
try {
|
|
16318
16404
|
const existingUserDoc = await this.userService.getUserById(firebaseUser.uid);
|
|
@@ -16382,7 +16468,7 @@ ${stackTrace}`);
|
|
|
16382
16468
|
};
|
|
16383
16469
|
} catch (error) {
|
|
16384
16470
|
console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
|
|
16385
|
-
console.error("[AUTH] Error type:", (
|
|
16471
|
+
console.error("[AUTH] Error type:", (_d = error == null ? void 0 : error.constructor) == null ? void 0 : _d.name);
|
|
16386
16472
|
console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
|
|
16387
16473
|
console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
|
|
16388
16474
|
console.error("[AUTH] Error message:", error == null ? void 0 : error.message);
|
package/dist/index.mjs
CHANGED
|
@@ -15489,6 +15489,73 @@ ${stackTrace}`);
|
|
|
15489
15489
|
console.log("[AUTH] AuthService initialized");
|
|
15490
15490
|
console.log("[AUTH] Initial auth.currentUser:", ((_a = this.auth.currentUser) == null ? void 0 : _a.uid) || "NULL");
|
|
15491
15491
|
}
|
|
15492
|
+
/**
|
|
15493
|
+
* Waits for Firebase Auth state to settle after sign-in.
|
|
15494
|
+
*
|
|
15495
|
+
* In React Native with AsyncStorage persistence, there's a critical issue:
|
|
15496
|
+
* 1. signInWithCredential() sets auth.currentUser in memory immediately
|
|
15497
|
+
* 2. But AsyncStorage persistence happens asynchronously
|
|
15498
|
+
* 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
|
|
15499
|
+
* 4. This causes auth.currentUser to become NULL even after it was set
|
|
15500
|
+
*
|
|
15501
|
+
* This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
|
|
15502
|
+
* It ensures the auth state persists through AsyncStorage operations.
|
|
15503
|
+
*
|
|
15504
|
+
* @param expectedUid - The UID we expect to see in auth.currentUser
|
|
15505
|
+
* @param timeoutMs - Maximum time to wait (default 5 seconds)
|
|
15506
|
+
* @returns Promise that resolves when auth state is ready and stable
|
|
15507
|
+
*/
|
|
15508
|
+
async waitForAuthStateToSettle(expectedUid, timeoutMs = 5e3) {
|
|
15509
|
+
var _a, _b, _c;
|
|
15510
|
+
if (((_a = this.auth.currentUser) == null ? void 0 : _a.uid) === expectedUid) {
|
|
15511
|
+
console.log("[AUTH] Auth state appears set, waiting for stability...");
|
|
15512
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
15513
|
+
if (((_b = this.auth.currentUser) == null ? void 0 : _b.uid) === expectedUid) {
|
|
15514
|
+
console.log("[AUTH] \u2705 Auth state stable for:", expectedUid);
|
|
15515
|
+
return;
|
|
15516
|
+
}
|
|
15517
|
+
}
|
|
15518
|
+
console.log("[AUTH] Waiting for auth state to settle for:", expectedUid);
|
|
15519
|
+
console.log("[AUTH] Current auth.currentUser:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
|
|
15520
|
+
return new Promise((resolve, reject) => {
|
|
15521
|
+
const startTime = Date.now();
|
|
15522
|
+
let resolved = false;
|
|
15523
|
+
const unsubscribe = onAuthStateChanged(this.auth, (user) => {
|
|
15524
|
+
if (resolved) return;
|
|
15525
|
+
const currentUid = (user == null ? void 0 : user.uid) || null;
|
|
15526
|
+
console.log("[AUTH] onAuthStateChanged fired:", currentUid || "NULL");
|
|
15527
|
+
if (currentUid === expectedUid) {
|
|
15528
|
+
setTimeout(() => {
|
|
15529
|
+
var _a2;
|
|
15530
|
+
if (resolved) return;
|
|
15531
|
+
if (((_a2 = this.auth.currentUser) == null ? void 0 : _a2.uid) === expectedUid) {
|
|
15532
|
+
resolved = true;
|
|
15533
|
+
unsubscribe();
|
|
15534
|
+
clearTimeout(timeout);
|
|
15535
|
+
const elapsed = Date.now() - startTime;
|
|
15536
|
+
console.log(`[AUTH] \u2705 Auth state settled and stable after ${elapsed}ms for:`, expectedUid);
|
|
15537
|
+
resolve();
|
|
15538
|
+
} else {
|
|
15539
|
+
console.warn("[AUTH] \u26A0\uFE0F Auth state became NULL after being set, waiting more...");
|
|
15540
|
+
}
|
|
15541
|
+
}, 300);
|
|
15542
|
+
} else if (currentUid === null && Date.now() - startTime > 1e3) {
|
|
15543
|
+
console.error("[AUTH] \u274C Auth state became NULL after being set!");
|
|
15544
|
+
console.error("[AUTH] This indicates AsyncStorage persistence issue");
|
|
15545
|
+
}
|
|
15546
|
+
});
|
|
15547
|
+
const timeout = setTimeout(() => {
|
|
15548
|
+
var _a2, _b2;
|
|
15549
|
+
if (resolved) return;
|
|
15550
|
+
resolved = true;
|
|
15551
|
+
unsubscribe();
|
|
15552
|
+
console.error("[AUTH] \u274C Timeout waiting for auth state to settle");
|
|
15553
|
+
console.error("[AUTH] Expected UID:", expectedUid);
|
|
15554
|
+
console.error("[AUTH] Actual auth.currentUser:", ((_a2 = this.auth.currentUser) == null ? void 0 : _a2.uid) || "NULL");
|
|
15555
|
+
reject(new Error(`Timeout waiting for auth state to settle. Expected: ${expectedUid}, Got: ${((_b2 = this.auth.currentUser) == null ? void 0 : _b2.uid) || "NULL"}`));
|
|
15556
|
+
}, timeoutMs);
|
|
15557
|
+
});
|
|
15558
|
+
}
|
|
15492
15559
|
/**
|
|
15493
15560
|
* Registruje novog korisnika sa email-om i lozinkom
|
|
15494
15561
|
*/
|
|
@@ -16241,6 +16308,9 @@ ${stackTrace}`);
|
|
|
16241
16308
|
const credential = GoogleAuthProvider.credential(idToken);
|
|
16242
16309
|
const { user: firebaseUser } = await signInWithCredential(this.auth, credential);
|
|
16243
16310
|
console.log("[AUTH] Firebase user signed in:", firebaseUser.uid);
|
|
16311
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16312
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
16313
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16244
16314
|
const existingUser = await this.userService.getUserById(firebaseUser.uid);
|
|
16245
16315
|
if (existingUser) {
|
|
16246
16316
|
console.log("[AUTH] Existing user found, returning profile:", existingUser.uid);
|
|
@@ -16266,7 +16336,7 @@ ${stackTrace}`);
|
|
|
16266
16336
|
* @returns Object containing user, practitioner (if exists), and draft profiles (if any)
|
|
16267
16337
|
*/
|
|
16268
16338
|
async signUpPractitionerWithGoogle(idToken) {
|
|
16269
|
-
var _a, _b, _c;
|
|
16339
|
+
var _a, _b, _c, _d;
|
|
16270
16340
|
try {
|
|
16271
16341
|
console.log("[AUTH] Starting practitioner Google Sign-In/Sign-Up");
|
|
16272
16342
|
let email;
|
|
@@ -16300,6 +16370,9 @@ ${stackTrace}`);
|
|
|
16300
16370
|
console.log("[AUTH] User exists with Google provider, signing in");
|
|
16301
16371
|
const credential2 = GoogleAuthProvider.credential(idToken);
|
|
16302
16372
|
const { user: firebaseUser2 } = await signInWithCredential(this.auth, credential2);
|
|
16373
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16374
|
+
await this.waitForAuthStateToSettle(firebaseUser2.uid);
|
|
16375
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16303
16376
|
let existingUser2 = null;
|
|
16304
16377
|
try {
|
|
16305
16378
|
existingUser2 = await this.userService.getUserById(firebaseUser2.uid);
|
|
@@ -16311,6 +16384,16 @@ ${stackTrace}`);
|
|
|
16311
16384
|
errorType: (_a = userError == null ? void 0 : userError.constructor) == null ? void 0 : _a.name,
|
|
16312
16385
|
isAuthError: userError instanceof AuthError
|
|
16313
16386
|
});
|
|
16387
|
+
if (!this.auth.currentUser || this.auth.currentUser.uid !== firebaseUser2.uid) {
|
|
16388
|
+
console.error("[AUTH] \u274C auth.currentUser became NULL before draft profile query!");
|
|
16389
|
+
console.error("[AUTH] Expected UID:", firebaseUser2.uid);
|
|
16390
|
+
console.error("[AUTH] Actual auth.currentUser:", ((_b = this.auth.currentUser) == null ? void 0 : _b.uid) || "NULL");
|
|
16391
|
+
console.log("[AUTH] Re-signing in to restore auth state before query...");
|
|
16392
|
+
const credential3 = GoogleAuthProvider.credential(idToken);
|
|
16393
|
+
await signInWithCredential(this.auth, credential3);
|
|
16394
|
+
await this.waitForAuthStateToSettle(firebaseUser2.uid, 2e3);
|
|
16395
|
+
console.log("[AUTH] \u2705 Auth state restored, proceeding with query");
|
|
16396
|
+
}
|
|
16314
16397
|
const practitionerService2 = new PractitionerService(this.db, this.auth, this.app);
|
|
16315
16398
|
const draftProfiles3 = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
|
|
16316
16399
|
console.log("[AUTH] Draft profiles check result:", {
|
|
@@ -16332,7 +16415,7 @@ ${stackTrace}`);
|
|
|
16332
16415
|
);
|
|
16333
16416
|
}
|
|
16334
16417
|
console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
|
|
16335
|
-
console.log("[AUTH] auth.currentUser at User creation time:", ((
|
|
16418
|
+
console.log("[AUTH] auth.currentUser at User creation time:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
|
|
16336
16419
|
try {
|
|
16337
16420
|
const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
|
|
16338
16421
|
skipProfileCreation: true
|
|
@@ -16400,6 +16483,9 @@ ${stackTrace}`);
|
|
|
16400
16483
|
}
|
|
16401
16484
|
throw error;
|
|
16402
16485
|
}
|
|
16486
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16487
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
16488
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16403
16489
|
let existingUser = null;
|
|
16404
16490
|
try {
|
|
16405
16491
|
const existingUserDoc = await this.userService.getUserById(firebaseUser.uid);
|
|
@@ -16469,7 +16555,7 @@ ${stackTrace}`);
|
|
|
16469
16555
|
};
|
|
16470
16556
|
} catch (error) {
|
|
16471
16557
|
console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
|
|
16472
|
-
console.error("[AUTH] Error type:", (
|
|
16558
|
+
console.error("[AUTH] Error type:", (_d = error == null ? void 0 : error.constructor) == null ? void 0 : _d.name);
|
|
16473
16559
|
console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
|
|
16474
16560
|
console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
|
|
16475
16561
|
console.error("[AUTH] Error message:", error == null ? void 0 : error.message);
|
package/package.json
CHANGED
|
@@ -110,6 +110,87 @@ export class AuthService extends BaseService {
|
|
|
110
110
|
console.log('[AUTH] Initial auth.currentUser:', this.auth.currentUser?.uid || 'NULL');
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Waits for Firebase Auth state to settle after sign-in.
|
|
115
|
+
*
|
|
116
|
+
* In React Native with AsyncStorage persistence, there's a critical issue:
|
|
117
|
+
* 1. signInWithCredential() sets auth.currentUser in memory immediately
|
|
118
|
+
* 2. But AsyncStorage persistence happens asynchronously
|
|
119
|
+
* 3. If AsyncStorage reads an old NULL value, it can OVERWRITE the current auth state
|
|
120
|
+
* 4. This causes auth.currentUser to become NULL even after it was set
|
|
121
|
+
*
|
|
122
|
+
* This method uses onAuthStateChanged to wait for the auth state to be SET and STABLE.
|
|
123
|
+
* It ensures the auth state persists through AsyncStorage operations.
|
|
124
|
+
*
|
|
125
|
+
* @param expectedUid - The UID we expect to see in auth.currentUser
|
|
126
|
+
* @param timeoutMs - Maximum time to wait (default 5 seconds)
|
|
127
|
+
* @returns Promise that resolves when auth state is ready and stable
|
|
128
|
+
*/
|
|
129
|
+
private async waitForAuthStateToSettle(expectedUid: string, timeoutMs: number = 5000): Promise<void> {
|
|
130
|
+
// If already correct, still wait a bit to ensure it's stable (not just set in memory)
|
|
131
|
+
if (this.auth.currentUser?.uid === expectedUid) {
|
|
132
|
+
console.log('[AUTH] Auth state appears set, waiting for stability...');
|
|
133
|
+
// Wait a small amount to ensure AsyncStorage persistence completes
|
|
134
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
135
|
+
// Check again after wait
|
|
136
|
+
if (this.auth.currentUser?.uid === expectedUid) {
|
|
137
|
+
console.log('[AUTH] ✅ Auth state stable for:', expectedUid);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log('[AUTH] Waiting for auth state to settle for:', expectedUid);
|
|
143
|
+
console.log('[AUTH] Current auth.currentUser:', this.auth.currentUser?.uid || 'NULL');
|
|
144
|
+
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
let resolved = false;
|
|
148
|
+
|
|
149
|
+
// Use onAuthStateChanged to wait for auth state to be SET
|
|
150
|
+
// This is more reliable than polling auth.currentUser
|
|
151
|
+
const unsubscribe = onAuthStateChanged(this.auth, (user) => {
|
|
152
|
+
if (resolved) return;
|
|
153
|
+
|
|
154
|
+
const currentUid = user?.uid || null;
|
|
155
|
+
console.log('[AUTH] onAuthStateChanged fired:', currentUid || 'NULL');
|
|
156
|
+
|
|
157
|
+
if (currentUid === expectedUid) {
|
|
158
|
+
// Auth state is set, but wait a bit more to ensure it's stable
|
|
159
|
+
// AsyncStorage might still be writing/reading
|
|
160
|
+
setTimeout(() => {
|
|
161
|
+
if (resolved) return;
|
|
162
|
+
|
|
163
|
+
// Final check - is it still set?
|
|
164
|
+
if (this.auth.currentUser?.uid === expectedUid) {
|
|
165
|
+
resolved = true;
|
|
166
|
+
unsubscribe();
|
|
167
|
+
clearTimeout(timeout);
|
|
168
|
+
const elapsed = Date.now() - startTime;
|
|
169
|
+
console.log(`[AUTH] ✅ Auth state settled and stable after ${elapsed}ms for:`, expectedUid);
|
|
170
|
+
resolve();
|
|
171
|
+
} else {
|
|
172
|
+
console.warn('[AUTH] ⚠️ Auth state became NULL after being set, waiting more...');
|
|
173
|
+
}
|
|
174
|
+
}, 300); // Wait 300ms for AsyncStorage to stabilize
|
|
175
|
+
} else if (currentUid === null && Date.now() - startTime > 1000) {
|
|
176
|
+
// Auth state became NULL after being set - this is the bug we're trying to fix
|
|
177
|
+
console.error('[AUTH] ❌ Auth state became NULL after being set!');
|
|
178
|
+
console.error('[AUTH] This indicates AsyncStorage persistence issue');
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const timeout = setTimeout(() => {
|
|
183
|
+
if (resolved) return;
|
|
184
|
+
resolved = true;
|
|
185
|
+
unsubscribe();
|
|
186
|
+
console.error('[AUTH] ❌ Timeout waiting for auth state to settle');
|
|
187
|
+
console.error('[AUTH] Expected UID:', expectedUid);
|
|
188
|
+
console.error('[AUTH] Actual auth.currentUser:', this.auth.currentUser?.uid || 'NULL');
|
|
189
|
+
reject(new Error(`Timeout waiting for auth state to settle. Expected: ${expectedUid}, Got: ${this.auth.currentUser?.uid || 'NULL'}`));
|
|
190
|
+
}, timeoutMs);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
113
194
|
/**
|
|
114
195
|
* Registruje novog korisnika sa email-om i lozinkom
|
|
115
196
|
*/
|
|
@@ -1099,6 +1180,13 @@ export class AuthService extends BaseService {
|
|
|
1099
1180
|
const { user: firebaseUser } = await signInWithCredential(this.auth, credential);
|
|
1100
1181
|
console.log('[AUTH] Firebase user signed in:', firebaseUser.uid);
|
|
1101
1182
|
|
|
1183
|
+
// CRITICAL: Wait for auth state to settle before making Firestore queries
|
|
1184
|
+
// In React Native with AsyncStorage persistence, auth.currentUser can be NULL
|
|
1185
|
+
// immediately after signInWithCredential due to async persistence race condition
|
|
1186
|
+
console.log('[AUTH] Waiting for auth state to settle after sign-in...');
|
|
1187
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
1188
|
+
console.log('[AUTH] ✅ Auth state settled, proceeding with Firestore queries');
|
|
1189
|
+
|
|
1102
1190
|
// 4) Load our domain user document.
|
|
1103
1191
|
const existingUser = await this.userService.getUserById(firebaseUser.uid);
|
|
1104
1192
|
if (existingUser) {
|
|
@@ -1179,6 +1267,13 @@ export class AuthService extends BaseService {
|
|
|
1179
1267
|
const credential = GoogleAuthProvider.credential(idToken);
|
|
1180
1268
|
const { user: firebaseUser } = await signInWithCredential(this.auth, credential);
|
|
1181
1269
|
|
|
1270
|
+
// CRITICAL: Wait for auth state to settle before making Firestore queries
|
|
1271
|
+
// In React Native with AsyncStorage persistence, auth.currentUser can be NULL
|
|
1272
|
+
// immediately after signInWithCredential due to async persistence race condition
|
|
1273
|
+
console.log('[AUTH] Waiting for auth state to settle after sign-in...');
|
|
1274
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
1275
|
+
console.log('[AUTH] ✅ Auth state settled, proceeding with Firestore queries');
|
|
1276
|
+
|
|
1182
1277
|
let existingUser: User | null = null;
|
|
1183
1278
|
try {
|
|
1184
1279
|
existingUser = await this.userService.getUserById(firebaseUser.uid);
|
|
@@ -1193,6 +1288,25 @@ export class AuthService extends BaseService {
|
|
|
1193
1288
|
});
|
|
1194
1289
|
|
|
1195
1290
|
// Check for draft profiles before signing out
|
|
1291
|
+
// CRITICAL: Firestore queries can trigger AsyncStorage reads which overwrite auth.currentUser
|
|
1292
|
+
// If auth.currentUser is NULL, re-sign in immediately to restore it before the query
|
|
1293
|
+
if (!this.auth.currentUser || this.auth.currentUser.uid !== firebaseUser.uid) {
|
|
1294
|
+
console.error('[AUTH] ❌ auth.currentUser became NULL before draft profile query!');
|
|
1295
|
+
console.error('[AUTH] Expected UID:', firebaseUser.uid);
|
|
1296
|
+
console.error('[AUTH] Actual auth.currentUser:', this.auth.currentUser?.uid || 'NULL');
|
|
1297
|
+
console.log('[AUTH] Re-signing in to restore auth state before query...');
|
|
1298
|
+
|
|
1299
|
+
// Re-sign in with the credential to restore auth.currentUser
|
|
1300
|
+
// This is the most reliable way to ensure auth state is set before Firestore queries
|
|
1301
|
+
const credential = GoogleAuthProvider.credential(idToken);
|
|
1302
|
+
await signInWithCredential(this.auth, credential);
|
|
1303
|
+
|
|
1304
|
+
// Wait for auth state to settle after re-sign-in
|
|
1305
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid, 2000);
|
|
1306
|
+
|
|
1307
|
+
console.log('[AUTH] ✅ Auth state restored, proceeding with query');
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1196
1310
|
const practitionerService = new PractitionerService(this.db, this.auth, this.app);
|
|
1197
1311
|
const draftProfiles = await practitionerService.getDraftProfilesByEmail(normalizedEmail);
|
|
1198
1312
|
|
|
@@ -1309,6 +1423,13 @@ export class AuthService extends BaseService {
|
|
|
1309
1423
|
throw error;
|
|
1310
1424
|
}
|
|
1311
1425
|
|
|
1426
|
+
// CRITICAL: Wait for auth state to settle before making Firestore queries
|
|
1427
|
+
// In React Native with AsyncStorage persistence, auth.currentUser can be NULL
|
|
1428
|
+
// immediately after signInWithCredential due to async persistence race condition
|
|
1429
|
+
console.log('[AUTH] Waiting for auth state to settle after sign-in...');
|
|
1430
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
1431
|
+
console.log('[AUTH] ✅ Auth state settled, proceeding with Firestore queries');
|
|
1432
|
+
|
|
1312
1433
|
// Check for existing User document (in case user had email/password account that was just linked)
|
|
1313
1434
|
let existingUser: User | null = null;
|
|
1314
1435
|
try {
|