@blackcode_sa/metaestetics-api 1.14.16 → 1.14.17
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 +86 -3
- package/dist/index.mjs +86 -3
- package/package.json +1 -1
- package/src/services/auth/auth.service.ts +113 -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,13 @@ ${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] Waiting for auth state to recover...");
|
|
16305
|
+
await this.waitForAuthStateToSettle(firebaseUser2.uid, 2e3);
|
|
16306
|
+
}
|
|
16227
16307
|
const practitionerService2 = new PractitionerService(this.db, this.auth, this.app);
|
|
16228
16308
|
const draftProfiles3 = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
|
|
16229
16309
|
console.log("[AUTH] Draft profiles check result:", {
|
|
@@ -16245,7 +16325,7 @@ ${stackTrace}`);
|
|
|
16245
16325
|
);
|
|
16246
16326
|
}
|
|
16247
16327
|
console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
|
|
16248
|
-
console.log("[AUTH] auth.currentUser at User creation time:", ((
|
|
16328
|
+
console.log("[AUTH] auth.currentUser at User creation time:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
|
|
16249
16329
|
try {
|
|
16250
16330
|
const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
|
|
16251
16331
|
skipProfileCreation: true
|
|
@@ -16313,6 +16393,9 @@ ${stackTrace}`);
|
|
|
16313
16393
|
}
|
|
16314
16394
|
throw error;
|
|
16315
16395
|
}
|
|
16396
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16397
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
16398
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16316
16399
|
let existingUser = null;
|
|
16317
16400
|
try {
|
|
16318
16401
|
const existingUserDoc = await this.userService.getUserById(firebaseUser.uid);
|
|
@@ -16382,7 +16465,7 @@ ${stackTrace}`);
|
|
|
16382
16465
|
};
|
|
16383
16466
|
} catch (error) {
|
|
16384
16467
|
console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
|
|
16385
|
-
console.error("[AUTH] Error type:", (
|
|
16468
|
+
console.error("[AUTH] Error type:", (_d = error == null ? void 0 : error.constructor) == null ? void 0 : _d.name);
|
|
16386
16469
|
console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
|
|
16387
16470
|
console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
|
|
16388
16471
|
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,13 @@ ${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] Waiting for auth state to recover...");
|
|
16392
|
+
await this.waitForAuthStateToSettle(firebaseUser2.uid, 2e3);
|
|
16393
|
+
}
|
|
16314
16394
|
const practitionerService2 = new PractitionerService(this.db, this.auth, this.app);
|
|
16315
16395
|
const draftProfiles3 = await practitionerService2.getDraftProfilesByEmail(normalizedEmail);
|
|
16316
16396
|
console.log("[AUTH] Draft profiles check result:", {
|
|
@@ -16332,7 +16412,7 @@ ${stackTrace}`);
|
|
|
16332
16412
|
);
|
|
16333
16413
|
}
|
|
16334
16414
|
console.log("[AUTH] Draft profiles found, creating User document IMMEDIATELY after sign-in");
|
|
16335
|
-
console.log("[AUTH] auth.currentUser at User creation time:", ((
|
|
16415
|
+
console.log("[AUTH] auth.currentUser at User creation time:", ((_c = this.auth.currentUser) == null ? void 0 : _c.uid) || "NULL");
|
|
16336
16416
|
try {
|
|
16337
16417
|
const newUser = await this.userService.createUser(firebaseUser2, ["practitioner" /* PRACTITIONER */], {
|
|
16338
16418
|
skipProfileCreation: true
|
|
@@ -16400,6 +16480,9 @@ ${stackTrace}`);
|
|
|
16400
16480
|
}
|
|
16401
16481
|
throw error;
|
|
16402
16482
|
}
|
|
16483
|
+
console.log("[AUTH] Waiting for auth state to settle after sign-in...");
|
|
16484
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
16485
|
+
console.log("[AUTH] \u2705 Auth state settled, proceeding with Firestore queries");
|
|
16403
16486
|
let existingUser = null;
|
|
16404
16487
|
try {
|
|
16405
16488
|
const existingUserDoc = await this.userService.getUserById(firebaseUser.uid);
|
|
@@ -16469,7 +16552,7 @@ ${stackTrace}`);
|
|
|
16469
16552
|
};
|
|
16470
16553
|
} catch (error) {
|
|
16471
16554
|
console.error("[AUTH] Error in signUpPractitionerWithGoogle:", error);
|
|
16472
|
-
console.error("[AUTH] Error type:", (
|
|
16555
|
+
console.error("[AUTH] Error type:", (_d = error == null ? void 0 : error.constructor) == null ? void 0 : _d.name);
|
|
16473
16556
|
console.error("[AUTH] Error instanceof AuthError:", error instanceof AuthError);
|
|
16474
16557
|
console.error("[AUTH] Error code:", error == null ? void 0 : error.code);
|
|
16475
16558
|
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,17 @@ export class AuthService extends BaseService {
|
|
|
1193
1288
|
});
|
|
1194
1289
|
|
|
1195
1290
|
// Check for draft profiles before signing out
|
|
1291
|
+
// CRITICAL: Verify auth.currentUser is still set before Firestore query
|
|
1292
|
+
// AsyncStorage persistence can cause it to become NULL even after being set
|
|
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] Waiting for auth state to recover...');
|
|
1298
|
+
// Try to wait for it to come back
|
|
1299
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid, 2000);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1196
1302
|
const practitionerService = new PractitionerService(this.db, this.auth, this.app);
|
|
1197
1303
|
const draftProfiles = await practitionerService.getDraftProfilesByEmail(normalizedEmail);
|
|
1198
1304
|
|
|
@@ -1309,6 +1415,13 @@ export class AuthService extends BaseService {
|
|
|
1309
1415
|
throw error;
|
|
1310
1416
|
}
|
|
1311
1417
|
|
|
1418
|
+
// CRITICAL: Wait for auth state to settle before making Firestore queries
|
|
1419
|
+
// In React Native with AsyncStorage persistence, auth.currentUser can be NULL
|
|
1420
|
+
// immediately after signInWithCredential due to async persistence race condition
|
|
1421
|
+
console.log('[AUTH] Waiting for auth state to settle after sign-in...');
|
|
1422
|
+
await this.waitForAuthStateToSettle(firebaseUser.uid);
|
|
1423
|
+
console.log('[AUTH] ✅ Auth state settled, proceeding with Firestore queries');
|
|
1424
|
+
|
|
1312
1425
|
// Check for existing User document (in case user had email/password account that was just linked)
|
|
1313
1426
|
let existingUser: User | null = null;
|
|
1314
1427
|
try {
|