Profiles·Public

firebase

semver>=9.0.0postconditions30functions30last verified2026-04-17coverage score81%

Postconditions — what we check

  • signInWithEmailAndPassword · auth-error
    error
    WhenAny Firebase auth failure: invalid email (auth/invalid-email), wrong password (auth/wrong-password), user not found (auth/user-not-found), user disabled (auth/user-disabled), network failure (auth/network-request-failed), or too many requests (auth/too-many-requests).
    ThrowsFirebaseError with code property. Common codes: auth/invalid-email, auth/wrong-password, auth/user-not-found, auth/user-disabled, auth/network-request-failed, auth/too-many-requests. FirebaseError extends Error with code: string and customData: object.
    Required handlingCaller MUST wrap await signInWithEmailAndPassword() in try-catch. Auth failures are common in production — invalid credentials, disabled accounts. Unhandled rejection crashes the process or returns 500 to the user. try { const credential = await signInWithEmailAndPassword(auth, email, password); return credential.user; } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/wrong-password') throw new Error('Invalid password'); if (error.code === 'auth/user-not-found') throw new Error('User not found'); } throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[1][2]
  • createUserWithEmailAndPassword · auth-error
    error
    WhenAny Firebase auth failure: email already in use (auth/email-already-in-use), invalid email (auth/invalid-email), weak password (auth/weak-password), operation not allowed (auth/operation-not-allowed), or network failure.
    ThrowsFirebaseError with code. Common codes: auth/email-already-in-use, auth/invalid-email, auth/weak-password, auth/operation-not-allowed, auth/network-request-failed.
    Required handlingCaller MUST wrap await createUserWithEmailAndPassword() in try-catch. Registration failures are expected (email conflicts, weak passwords). try { const credential = await createUserWithEmailAndPassword(auth, email, password); return credential.user; } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/email-already-in-use') throw new Error('Email taken'); if (error.code === 'auth/weak-password') throw new Error('Password too weak'); } throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[3][2]
  • signInWithPopup · auth-error
    error
    WhenAny auth failure: popup blocked (auth/popup-blocked), user cancelled (auth/popup-closed-by-user), account exists with different credential (auth/account-exists-with-different-credential), network failure, or cancelled popup before completion (auth/cancelled-popup-request).
    ThrowsFirebaseError with code. Common codes: auth/popup-blocked, auth/popup-closed-by-user, auth/account-exists-with-different-credential, auth/cancelled-popup-request, auth/network-request-failed.
    Required handlingCaller MUST wrap await signInWithPopup() in try-catch. Popup blocking is common — adblockers and browser settings frequently block popups. User cancellation is also a normal flow. try { const result = await signInWithPopup(auth, provider); return result.user; } catch (error) { if (error instanceof FirebaseError && error.code === 'auth/popup-blocked') { // Fallback to redirect or inform user } throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[4][5]
  • getDocs · firestore-error
    error
    WhenAny Firestore failure: permission denied (permission-denied), network failure (unavailable), resource not found (not-found), invalid query arguments (invalid-argument), or unauthenticated (unauthenticated).
    ThrowsFirebaseError with code. Common codes: permission-denied, unavailable, not-found, invalid-argument, unauthenticated, resource-exhausted (quota).
    Required handlingCaller MUST wrap await getDocs() in try-catch. Permission denied errors happen when Firestore Security Rules block access. Network failures occur in offline scenarios or during Firebase outages. try { const snapshot = await getDocs(q); return snapshot.docs.map(doc => doc.data()); } catch (error) { console.error('Firestore query failed:', error.message); throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[6][7]
  • addDoc · firestore-error
    error
    WhenAny Firestore failure: permission denied, invalid data (undefined values, circular references), network failure, or quota exceeded.
    ThrowsFirebaseError with code. Common codes: permission-denied, invalid-argument, unavailable, unauthenticated, resource-exhausted.
    Required handlingCaller MUST wrap await addDoc() in try-catch. Permission denied is common when users are not authenticated or Firestore Security Rules block writes. try { const docRef = await addDoc(collection(db, 'items'), data); return docRef.id; } catch (error) { console.error('Failed to add document:', error.message); throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[8][9]
  • setDoc · firestore-error
    error
    WhenAny Firestore failure: permission denied, invalid data, network failure, or quota exceeded.
    ThrowsFirebaseError with code. Common codes: permission-denied, invalid-argument, unavailable, unauthenticated, resource-exhausted.
    Required handlingCaller MUST wrap await setDoc() in try-catch. try { await setDoc(doc(db, 'users', userId), userData); } catch (error) { console.error('Failed to set document:', error.message); throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[10][9]
  • updateDoc · firestore-error
    error
    WhenAny Firestore failure: document not found (not-found), permission denied, invalid data, network failure, or unauthenticated.
    ThrowsFirebaseError with code. Common codes: not-found, permission-denied, invalid-argument, unavailable, unauthenticated.
    Required handlingCaller MUST wrap await updateDoc() in try-catch. updateDoc() throws not-found if the document doesn't exist (unlike setDoc). try { await updateDoc(docRef, { lastUpdated: new Date() }); } catch (error) { console.error('Failed to update document:', error.message); throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[11][9]
  • deleteDoc · firestore-error
    error
    WhenAny Firestore failure: permission denied, network failure, or unauthenticated. (Does NOT throw if document doesn't exist.)
    ThrowsFirebaseError with code. Common codes: permission-denied, unavailable, unauthenticated, resource-exhausted.
    Required handlingCaller MUST wrap await deleteDoc() in try-catch. try { await deleteDoc(doc(db, 'items', itemId)); } catch (error) { console.error('Failed to delete document:', error.message); throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[12][13]
  • sendPasswordResetEmail · auth-send-password-reset-invalid-email
    error
    WhensendPasswordResetEmail() called without try-catch when email is invalid format or the Auth instance is misconfigured.
    ThrowsFirebaseError with code: auth/invalid-email (malformed email address), auth/missing-email (empty email), auth/invalid-api-key (bad Firebase config), auth/network-request-failed (network failure), auth/too-many-requests (rate limit exceeded). Note: auth/user-not-found is NOT thrown when Email Enumeration Protection is enabled (the default since 2023) — Firebase returns success silently for unknown emails.
    Required handlingCaller MUST wrap await sendPasswordResetEmail() in try-catch. auth/invalid-email means client-side validation should run first. auth/too-many-requests means implement rate limiting in the UI. NEVER tell users whether the email exists — return generic "if account exists, email was sent". try { await sendPasswordResetEmail(auth, email); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/invalid-email') throw new Error('Invalid email format'); if (error.code === 'auth/too-many-requests') throw new Error('Too many attempts'); } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilitysilent
    Sources[14][15]
  • sendEmailVerification · auth-send-email-verification-error
    error
    WhensendEmailVerification() called without try-catch.
    ThrowsFirebaseError with code: auth/too-many-requests (sending too fast), auth/user-token-expired (user session expired — requires re-authentication), auth/network-request-failed (network failure), auth/user-disabled (account suspended), auth/invalid-user-token (user token invalid — session may be stale).
    Required handlingCaller MUST wrap await sendEmailVerification() in try-catch. auth/too-many-requests: Firebase limits verification email frequency — handle gracefully and inform user to wait before resending. auth/user-token-expired: User must sign in again before verification can be sent. try { await sendEmailVerification(user); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/too-many-requests') { throw new Error('Verification email already sent. Please wait before resending.'); } } throw error; }
    costlowin prodimmediate exceptionusers seeauthentication failurevisibilitysilent
    Sources[16][17]
  • deleteUser · auth-delete-user-requires-recent-login
    error
    WhendeleteUser() called without try-catch when user has not recently authenticated.
    ThrowsFirebaseError with code: auth/requires-recent-login (user's last sign-in was too long ago — must re-authenticate before this security-sensitive operation), auth/user-not-found (user was already deleted — race condition), auth/network-request-failed (network failure), auth/user-disabled (account was suspended).
    Required handlingCaller MUST wrap await deleteUser() in try-catch. auth/requires-recent-login is THE most important case: prompt user to sign in again using reauthenticateWithCredential() before retrying. This is the standard Firebase security pattern for sensitive operations. try { await deleteUser(user); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/requires-recent-login') { // Prompt re-authentication flow, then retry await reauthenticateWithCredential(user, credential); await deleteUser(user); } } throw error; }
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[18][19]
  • signOut · auth-sign-out-error
    warning
    WhensignOut() called without try-catch.
    ThrowsFirebaseError with code: auth/network-request-failed (network failure during token revocation), auth/internal-error (internal Firebase error, rare). Note: signOut() clears local auth state even if the server request fails, so users are effectively signed out locally even on error.
    Required handlingCaller MUST wrap await signOut() in try-catch to prevent unhandled rejections. Network failures during signOut are rare but possible. The local session is cleared regardless, so handle gracefully (log the error, redirect to login page). try { await signOut(auth); router.push('/login'); } catch (error) { // Sign out failed on server, but local session is cleared console.error('Sign out error:', error); router.push('/login'); // Redirect regardless }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[20]
  • getIdToken · auth-get-id-token-expired
    error
    WhengetIdToken() called without try-catch when user session is expired or revoked.
    ThrowsFirebaseError with code: auth/user-token-expired (token expired and cannot be refreshed — user must sign in again), auth/user-disabled (account suspended while token was valid), auth/user-not-found (user deleted), auth/network-request-failed (network failure during token refresh), auth/invalid-user-token (token is malformed).
    Required handlingCaller MUST wrap await getIdToken() in try-catch. auth/user-token-expired is the most common case — user session invalidated (password changed, token revoked from console, user deleted). On token errors, sign the user out and redirect to login. try { const token = await getIdToken(user); // Use token in Authorization header return fetch('/api/...', { headers: { Authorization: `Bearer ${token}` } }); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/user-token-expired' || error.code === 'auth/user-not-found') { await signOut(auth); router.push('/login'); } } throw error; }
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[21]
  • updateEmail · auth-update-email-requires-recent-login
    error
    WhenupdateEmail() called without try-catch when user session is stale.
    ThrowsFirebaseError with code: auth/requires-recent-login (must re-authenticate before changing email — security requirement), auth/email-already-in-use (email taken by another account), auth/invalid-email (malformed email), auth/operation-not-allowed (Email Enumeration Protection enabled — use verifyBeforeUpdateEmail instead), auth/network-request-failed (network failure).
    Required handlingCaller MUST wrap await updateEmail() in try-catch. auth/requires-recent-login is the most common error — prompt re-authentication. IMPORTANT: auth/operation-not-allowed means Email Enumeration Protection is enabled (default since 2023) — migrate to verifyBeforeUpdateEmail() which is the secure alternative. try { await updateEmail(user, newEmail); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/requires-recent-login') { throw new Error('Please sign in again to change your email'); } if (error.code === 'auth/email-already-in-use') { throw new Error('Email already in use'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[22][23]
  • updatePassword · auth-update-password-error
    error
    WhenupdatePassword() called without try-catch.
    ThrowsFirebaseError with code: auth/requires-recent-login (must re-authenticate — changing passwords is a security-sensitive operation), auth/weak-password (password too short, usually < 6 characters), auth/network-request-failed (network failure), auth/user-disabled (account suspended).
    Required handlingCaller MUST wrap await updatePassword() in try-catch. auth/requires-recent-login requires prompting the user to sign in again. auth/weak-password should be caught with client-side validation first. try { await updatePassword(user, newPassword); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/requires-recent-login') { throw new Error('Please sign in again to change your password'); } if (error.code === 'auth/weak-password') { throw new Error('Password must be at least 6 characters'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[24][25]
  • confirmPasswordReset · auth-confirm-password-reset-error
    error
    WhenconfirmPasswordReset() called without try-catch when the reset code is invalid or expired.
    ThrowsFirebaseError with code: auth/expired-action-code (reset link older than 1 hour — user must request a new one), auth/invalid-action-code (malformed or already-used code), auth/user-not-found (account deleted since reset was requested), auth/user-disabled (account suspended), auth/weak-password (new password too short), auth/network-request-failed (network failure).
    Required handlingCaller MUST wrap await confirmPasswordReset() in try-catch. auth/expired-action-code is the most common error — reset links expire after 1 hour. Prompt the user to request a new reset email. auth/invalid-action-code may mean the link was already used (single-use codes). try { await confirmPasswordReset(auth, oobCode, newPassword); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/expired-action-code') { throw new Error('Reset link has expired. Please request a new one.'); } if (error.code === 'auth/invalid-action-code') { throw new Error('Reset link is invalid or has already been used.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[26]
  • getDoc · firestore-get-doc-error
    error
    WhengetDoc() called without try-catch.
    ThrowsFirebaseError (FirestoreError) with code: permission-denied (Firestore Security Rules block access), unavailable (network failure or Firebase outage — may resolve after retry), unauthenticated (user not signed in when rules require auth), not-found (collection or database doesn't exist — not thrown for missing docs). IMPORTANT: Returns empty DocumentSnapshot (snapshot.exists() === false) for missing documents — does NOT throw. Check snapshot.exists() before accessing snapshot.data().
    Required handlingCaller MUST wrap await getDoc() in try-catch AND check snapshot.exists() before access. permission-denied is very common during development (Firestore rules misconfigured). Failing to check exists() causes data() to return undefined, causing null reference errors. try { const snapshot = await getDoc(doc(db, 'users', userId)); if (!snapshot.exists()) { throw new Error('User not found'); } return snapshot.data(); } catch (error) { if (error instanceof FirebaseError) { console.error('Firestore read failed:', error.code, error.message); } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[27][7]
  • runTransaction · firestore-transaction-contention
    error
    WhenrunTransaction() called without try-catch when there is high write contention or the transaction function throws.
    ThrowsFirebaseError (FirestoreError) with code: aborted (failed to commit after 5 retries due to high write contention), permission-denied (Security Rules block a read or write inside the transaction), unavailable (network failure), failed-precondition (transaction read document that no longer exists), resource-exhausted (quota exceeded), invalid-argument (more than 500 writes in one transaction). Also re-throws any error thrown inside the updateFunction.
    Required handlingCaller MUST wrap await runTransaction() in try-catch. aborted after 5 retries is the most critical case — indicates hot document (high contention). Consider sharding the counter or using FieldValue.increment() instead of transactions for counters. Errors thrown inside updateFunction propagate as-is — wrap with custom errors for clarity. try { const result = await runTransaction(db, async (t) => { const docSnap = await t.get(docRef); if (!docSnap.exists()) throw new Error('Document not found'); t.update(docRef, { count: docSnap.data().count + 1 }); return docSnap.data().count + 1; }); return result; } catch (error) { if (error instanceof FirebaseError && error.code === 'aborted') { throw new Error('Transaction failed after retries — high contention on document'); } throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilitysilent
    Sources[28][29]
  • uploadBytes · storage-upload-bytes-error
    error
    WhenuploadBytes() called without try-catch.
    ThrowsStorageError (extends FirebaseError) with code: storage/unauthorized (Security Rules block the upload — user not authenticated or path not allowed), storage/quota-exceeded (Firebase Storage quota for the project exceeded), storage/canceled (upload was cancelled), storage/retry-limit-exceeded (network too slow or unstable, max retries reached), storage/invalid-checksum (data corrupted in transit), storage/unauthenticated (no authenticated user). StorageError.code is prefixed with 'storage/'.
    Required handlingCaller MUST wrap await uploadBytes() in try-catch. storage/unauthorized is the most common error — check Firebase Storage Security Rules. storage/quota-exceeded requires checking Firebase project billing/quota limits. storage/retry-limit-exceeded indicates persistent network issues. try { const result = await uploadBytes(storageRef, file); return result.ref.fullPath; } catch (error) { if (error instanceof StorageError) { if (error.code === 'storage/unauthorized') { throw new Error('Not authorized to upload files'); } if (error.code === 'storage/quota-exceeded') { throw new Error('Storage quota exceeded'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[30][31]
  • getDownloadURL · storage-get-download-url-error
    error
    WhengetDownloadURL() called without try-catch.
    ThrowsStorageError (extends FirebaseError) with code: storage/object-not-found (file was deleted or path is wrong — very common bug when referencing stale paths), storage/unauthorized (Security Rules deny read access), storage/no-download-url (file exists but has no public download URL — requires making the bucket public or using signed URLs), storage/bucket-not-found (wrong bucket name in Firebase config), storage/unauthenticated (rules require auth).
    Required handlingCaller MUST wrap await getDownloadURL() in try-catch. storage/object-not-found is the most common error — file was deleted, moved, or the stored path is wrong (race condition between upload and read is common). Validate file existence before serving download URLs to users. try { const url = await getDownloadURL(ref(storage, filePath)); return url; } catch (error) { if (error instanceof StorageError) { if (error.code === 'storage/object-not-found') { throw new Error('File not found'); } if (error.code === 'storage/unauthorized') { throw new Error('Not authorized to access this file'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[32][33]
  • signInWithEmailLink · email-link-expired-or-invalid
    error
    WhensignInWithEmailLink() called without try-catch. The email link has expired or was already used, or the link doesn't match the email address provided.
    ThrowsFirebaseError with code: auth/expired-action-code (link expired — 10 minute TTL), auth/invalid-action-code (link already used or malformed), auth/invalid-email (email doesn't match the one the link was sent to), auth/user-disabled (account disabled after link was sent), auth/network-request-failed (network failure).
    Required handlingCaller MUST wrap await signInWithEmailLink() in try-catch. Expired and already-used links are the most common production failures — users often click links multiple times or wait too long. Each link is single-use and has a 10-minute expiration. try { const result = await signInWithEmailLink(auth, email, window.location.href); window.localStorage.removeItem('emailForSignIn'); return result.user; } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/expired-action-code') { throw new Error('Sign-in link has expired. Please request a new one.'); } if (error.code === 'auth/invalid-action-code') { throw new Error('Sign-in link already used. Please request a new one.'); } if (error.code === 'auth/invalid-email') { throw new Error('Email does not match the sign-in link.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[34][35]
  • signInAnonymously · anonymous-auth-not-enabled-or-quota-exceeded
    error
    WhensignInAnonymously() called without try-catch. Anonymous auth not enabled in Firebase Console, or quota for anonymous accounts exceeded.
    ThrowsFirebaseError with code: auth/operation-not-allowed (anonymous authentication not enabled in Firebase Console — frequent misconfiguration in new projects), auth/quota-exceeded (new anonymous sign-ups rate-limited, common when deployed to production without proper settings), auth/network-request-failed (network failure).
    Required handlingCaller MUST wrap await signInAnonymously() in try-catch. auth/operation-not-allowed means Anonymous sign-in is disabled in Firebase Console — developers often forget to enable it for new environments (staging, production). auth/quota-exceeded means Firebase is rate-limiting new anonymous sign-ups. try { const result = await signInAnonymously(auth); return result.user; } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/operation-not-allowed') { throw new Error('Anonymous sign-in is disabled. Enable it in Firebase Console.'); } if (error.code === 'auth/quota-exceeded') { throw new Error('Too many anonymous sign-in attempts. Please try again later.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[36][37]
  • updateProfile · update-profile-error
    warning
    WhenupdateProfile() called without try-catch. User's token expired, user was deleted, or network failure.
    ThrowsFirebaseError with code: auth/network-request-failed (network failure during profile update — common in flaky connections), auth/user-token-expired (user's auth token has expired, requires re-authentication), auth/user-not-found (user account was deleted between sign-in and the profile update call).
    Required handlingCaller MUST wrap await updateProfile() in try-catch. auth/user-token-expired requires the user to sign in again. This function is commonly called immediately after createUserWithEmailAndPassword() in onboarding flows — both should be wrapped together. try { await updateProfile(auth.currentUser, { displayName: name, photoURL: avatarUrl }); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/network-request-failed') { throw new Error('Network error updating profile. Please try again.'); } if (error.code === 'auth/user-token-expired') { throw new Error('Session expired. Please sign in again.'); } } throw error; }
    costlowin prodimmediate exceptionusers seelost datavisibilitysilent
    Sources[38][39]
  • linkWithCredential · link-credential-conflict
    error
    WhenlinkWithCredential() called without try-catch. The credential is already associated with another Firebase account, or an account with that email already exists.
    ThrowsFirebaseError with code: auth/credential-already-in-use (the credential is already linked to a different Firebase user account — cannot link the same Google/GitHub account to multiple Firebase users), auth/account-exists-with-different-credential (an account with the same email already exists but uses a different sign-in method — e.g. user has email/password account and tries to link Google with same email), auth/email-already-in-use (for email/password credential linking when email is taken), auth/provider-already-linked (user already has this provider linked), auth/requires-recent-login (security-sensitive operation requires recent sign-in).
    Required handlingCaller MUST wrap await linkWithCredential() in try-catch. auth/credential-already-in-use is the most important case — the linked credential's user needs to be merged or the conflict resolved. auth/account-exists-with-different-credential is very common in social auth flows where users try to link an OAuth account that matches an existing email/password account. try { const result = await linkWithCredential(user, credential); return result.user; } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/credential-already-in-use') { throw new Error('This account is already linked to another user.'); } if (error.code === 'auth/account-exists-with-different-credential') { throw new Error('An account with this email already exists with a different sign-in method.'); } if (error.code === 'auth/requires-recent-login') { throw new Error('Please sign in again before linking accounts.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[40][41]
  • reauthenticateWithCredential · reauth-credential-error
    error
    WhenreauthenticateWithCredential() called without try-catch. Wrong password, stale credential, or user mismatch.
    ThrowsFirebaseError with code: auth/wrong-password (incorrect password for email/password credential — user mistyped current password), auth/user-mismatch (credential does not correspond to the currently signed-in user — wrong account), auth/invalid-credential (the auth credential is malformed or has expired — OAuth token expired), auth/user-not-found (user account was deleted), auth/network-request-failed (network failure during re-auth).
    Required handlingCaller MUST wrap await reauthenticateWithCredential() in try-catch. This is required before deleteUser() or updateEmail() — if it fails, the subsequent sensitive operation must not proceed. auth/wrong-password is the most common failure. auth/user-mismatch means the credentials don't belong to the current user. const credential = EmailAuthProvider.credential(email, currentPassword); try { await reauthenticateWithCredential(auth.currentUser, credential); // Now safe to call deleteUser() or updateEmail() } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/wrong-password') { throw new Error('Current password is incorrect.'); } if (error.code === 'auth/user-mismatch') { throw new Error('Credential does not match the current user.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeauthentication failurevisibilityvisible
    Sources[42][43]
  • verifyBeforeUpdateEmail · verify-before-update-email-error
    error
    WhenverifyBeforeUpdateEmail() called without try-catch. Email already in use, requires recent login, or network failure.
    ThrowsFirebaseError with code: auth/email-already-in-use (new email already registered to another account), auth/requires-recent-login (security-sensitive operation — user must have signed in within the last few minutes), auth/invalid-email (new email address is malformed), auth/network-request-failed (network failure during verification email send), auth/operation-not-allowed (email/password accounts not enabled — unlikely but possible in Identity Platform configs).
    Required handlingCaller MUST wrap await verifyBeforeUpdateEmail() in try-catch. auth/requires-recent-login is the most common failure — the user must reauthenticate before changing their email. auth/email-already-in-use means the new email is taken. try { await verifyBeforeUpdateEmail(auth.currentUser, newEmail); // Tell user to check their new email inbox } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'auth/email-already-in-use') { throw new Error('This email address is already registered.'); } if (error.code === 'auth/requires-recent-login') { throw new Error('Please sign in again before changing your email.'); } } throw error; }
    costlowin prodimmediate exceptionusers seeauthentication failurevisibilitysilent
    Sources[44][45]
  • writeBatch.commit · batch-commit-permission-denied
    error
    Whenbatch.commit() called without try-catch. Firestore Security Rules deny one or more writes in the batch, or the batch exceeds 500 operations.
    ThrowsFirebaseError (FirestoreError) with code: permission-denied (Security Rules block one or more write operations in the batch — the entire batch fails atomically), not-found (a batch.update() or batch.delete() references a document that does not exist), resource-exhausted (batch exceeds 500 operations or rate limits), unavailable (Firestore temporarily unavailable — transient network/service issue), unauthenticated (user not authenticated and rules require auth). The WriteBatch.commit() Promise will never resolve while offline.
    Required handlingCaller MUST wrap await batch.commit() in try-catch. A single permission-denied write in the batch fails ALL writes atomically. Check that all document paths in the batch pass Security Rules before committing. Monitor for resource-exhausted if batches dynamically grow with user-generated content. const batch = writeBatch(db); batch.set(doc(db, 'users', userId), userData); batch.update(doc(db, 'counters', 'users'), { count: increment(1) }); try { await batch.commit(); } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'permission-denied') { throw new Error('Not authorized to perform this update.'); } if (error.code === 'resource-exhausted') { throw new Error('Batch too large or rate limit exceeded. Reduce batch size.'); } } throw error; }
    costhighin prodimmediate exceptionusers seelost datavisibilitysilent
    Sources[46][47]
  • getCountFromServer · count-from-server-error
    warning
    WhengetCountFromServer() called without try-catch. Firestore Security Rules deny the query, or the underlying index is not ready.
    ThrowsFirebaseError (FirestoreError) with code: permission-denied (Security Rules deny the underlying query the count is based on — common when the query has compound filters that require field-level auth), unauthenticated (user not authenticated and Security Rules require auth), failed-precondition (composite index not yet built for the query — very common during development when adding new queries), resource-exhausted (project quota exceeded or too many reads in short window), unavailable (Firestore temporarily unavailable).
    Required handlingCaller MUST wrap await getCountFromServer() in try-catch. failed-precondition with a message about missing indexes is very common during development — Firestore will include the index creation URL in the error message. permission-denied occurs when Security Rules don't allow the underlying collection read. try { const snapshot = await getCountFromServer(query(collection(db, 'orders'), where('userId', '==', userId))); return snapshot.data().count; } catch (error) { if (error instanceof FirebaseError) { if (error.code === 'permission-denied') { throw new Error('Not authorized to count this collection.'); } if (error.code === 'failed-precondition') { throw new Error('Missing Firestore index. Check Firebase Console.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[48][49]
  • deleteObject · delete-object-error
    error
    WhendeleteObject() called without try-catch. File does not exist, or Security Rules deny the delete operation.
    ThrowsStorageError (extends FirebaseError) with code: storage/object-not-found (file was already deleted or path is wrong — concurrent deletion is common in user-facing apps where users can delete from multiple sessions), storage/unauthorized (Security Rules deny the delete — user does not own the file or rules require ownership check), storage/unauthenticated (user is not authenticated but rules require auth), storage/retry-limit-exceeded (network failure with all retries exhausted).
    Required handlingCaller MUST wrap await deleteObject() in try-catch. storage/object-not-found should be treated as a success (idempotent delete is safe) or at minimum should not crash the user-facing operation. Always check Security Rules: rules must verify file ownership to prevent users deleting others' files. try { await deleteObject(ref(storage, filePath)); } catch (error) { if (error instanceof StorageError) { if (error.code === 'storage/object-not-found') { // File already deleted — treat as success for idempotent delete return; } if (error.code === 'storage/unauthorized') { throw new Error('Not authorized to delete this file.'); } } throw error; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilitysilent
    Sources[50][51]
  • httpsCallable · functions-call-unauthenticated-or-permission-denied
    error
    WhenhttpsCallable(functions, name) result called without try-catch. User not authenticated, permission denied, function not found, or internal server error.
    ThrowsFunctionsError (extends FirebaseError) with code: functions/unauthenticated (function requires Firebase Authentication and user is not signed in), functions/permission-denied (user is signed in but does not have permission to call this function — typically enforced via Firebase Auth claims check in the function), functions/not-found (function does not exist or was not deployed — common during development), functions/internal (unhandled exception in the Cloud Function — function threw an error not wrapped in HttpsError), functions/unavailable (Cloud Functions temporarily unavailable — transient), functions/deadline-exceeded (function execution timeout — 60s default), functions/resource-exhausted (quota exceeded — max concurrent calls reached).
    Required handlingCaller MUST wrap await fn(data) in try-catch, NOT await httpsCallable() itself. functions/unauthenticated means the user must sign in before calling the function. functions/internal means the Cloud Function itself crashed — check server logs. functions/permission-denied is an application-level authorization failure. Use error.code to distinguish user-facing errors from internal server errors. const sendInvite = httpsCallable(functions, 'sendInvite'); try { const result = await sendInvite({ email, organizationId }); return result.data; } catch (error) { if (error instanceof FunctionsError) { if (error.code === 'functions/unauthenticated') { throw new Error('Please sign in to perform this action.'); } if (error.code === 'functions/permission-denied') { throw new Error('You do not have permission to perform this action.'); } if (error.code === 'functions/internal') { throw new Error('Server error. Please try again later.'); } } throw error; }
    costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[52][53]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#signinwithemailandpassword
  2. [2]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/password-auth
  3. [3]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#createuserwithemailandpassword
  4. [4]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#signinwithpopup
  5. [5]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/google-signin
  6. [6]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.md#getdocs
  7. [7]firebase.google.com/docs/firestorehttps://firebase.google.com/docs/firestore/query-data/get-data
  8. [8]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.md#adddoc
  9. [9]firebase.google.com/docs/firestorehttps://firebase.google.com/docs/firestore/manage-data/add-data
  10. [10]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.md#setdoc
  11. [11]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.md#updatedoc
  12. [12]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.md#deletedoc
  13. [13]firebase.google.com/docs/firestorehttps://firebase.google.com/docs/firestore/manage-data/delete-data
  14. [14]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#sendpasswordresetemail
  15. [15]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#send_a_password_reset_email
  16. [16]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#sendemailverification
  17. [17]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#send_a_user_a_verification_email
  18. [18]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#deleteuser
  19. [19]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#delete_a_user
  20. [20]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#signout
  21. [21]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#getidtoken
  22. [22]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#updateemail
  23. [23]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#update_a_users_email
  24. [24]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#updatepassword
  25. [25]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#update_a_users_password
  26. [26]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth#confirmpasswordreset
  27. [27]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_#getdoc
  28. [28]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_#runtransaction
  29. [29]firebase.google.com/docs/firestorehttps://firebase.google.com/docs/firestore/manage-data/transactions
  30. [30]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/storage#uploadbytes
  31. [31]firebase.google.com/docs/storagehttps://firebase.google.com/docs/storage/web/upload-files
  32. [32]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/storage#getdownloadurl
  33. [33]firebase.google.com/docs/storagehttps://firebase.google.com/docs/storage/web/download-files
  34. [34]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/email-link-auth
  35. [35]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#signinwithemaillink
  36. [36]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/anonymous-auth
  37. [37]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#signinanonymously
  38. [38]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#updateprofile
  39. [39]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#update_a_users_profile
  40. [40]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#linkwithcredential
  41. [41]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/account-linking
  42. [42]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#reauthenticatewithcredential
  43. [43]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#re-authenticate_a_user
  44. [44]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/auth.md#verifybeforeupdateemail
  45. [45]firebase.google.com/docs/authhttps://firebase.google.com/docs/auth/web/manage-users#set_a_users_email_address
  46. [46]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.writebatch#writebatchcommit
  47. [47]firebase.google.com/docs/firestorehttps://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes
  48. [48]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/firestore_.md#getcountfromserver
  49. [49]firebase.google.com/docs/firestorehttps://firebase.google.com/docs/firestore/query-data/aggregation-queries
  50. [50]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/storage.md#deleteobject
  51. [51]firebase.google.com/docs/storagehttps://firebase.google.com/docs/storage/web/delete-files
  52. [52]firebase.google.com/docs/functionshttps://firebase.google.com/docs/functions/callable?gen=2nd
  53. [53]firebase.google.com/docs/referencehttps://firebase.google.com/docs/reference/js/functions.md#httpscallable
Need a different package?
Request a profile