The auth/missing-uid error occurs when using the Firebase Admin SDK to perform user operations (like createUser, getUser, updateUser, or setCustomUserClaims) without providing a valid UID parameter. This error indicates that a required user ID identifier is missing or empty.
The auth/missing-uid error is thrown by the Firebase Admin SDK when you attempt to call a user management function that requires a User ID (UID) without providing one, or by passing an empty or invalid UID value. Firebase Authentication requires every user to have a unique identifier (UID). This error occurs at the code level before the request reaches Firebase servers. It's a validation error that prevents invalid API calls, such as: - Calling `getUser()` without a UID - Creating a custom token with `createCustomToken()` without a UID - Updating user claims with `setCustomUserClaims()` without a UID - Any other Admin SDK operation that requires a UID parameter The UID must be a non-empty string (typically 1-128 characters). If your variable containing the UID is undefined, null, or an empty string, Firebase will throw this error.
Always check that the UID is a non-empty string before passing it to any Firebase Admin SDK method.
Incorrect - no validation:
import { getAuth } from 'firebase-admin/auth';
// ❌ Will fail if uid is undefined or empty
const customToken = await getAuth().createCustomToken(uid);Correct - validate first:
import { getAuth } from 'firebase-admin/auth';
async function createTokenSafely(uid: string | undefined) {
// Validate UID exists and is not empty
if (!uid || typeof uid !== 'string' || uid.trim() === '') {
throw new Error('UID is required and must be a non-empty string');
}
try {
const customToken = await getAuth().createCustomToken(uid);
return customToken;
} catch (error: any) {
console.error('Failed to create token:', error.code, error.message);
throw error;
}
}
// Usage
await createTokenSafely(uid);Add this validation before any Firebase Admin SDK call that requires a UID.
Make sure you're accessing the uid property from the correct object. Different Firebase SDKs and contexts use different property names.
Incorrect - wrong property names:
import { getAuth } from 'firebase-admin/auth';
// ❌ These will be undefined
const userId = user.id; // Wrong property
const userId = user.userId; // Wrong property
const userId = user.user_id; // Wrong property
const userId = userRecord.uid; // If user is undefined
// ❌ Will cause missing-uid error
const customToken = await getAuth().createCustomToken(userId);Correct - use the uid property:
import { getAuth } from 'firebase-admin/auth';
// ✅ Correct property name
const uid = user.uid;
// For Firebase Auth user record
const userRecord = await getAuth().getUser('some-uid');
const uid = userRecord.uid;
// For JWT decoded tokens
const decodedToken = await getAuth().verifyIdToken(idToken);
const uid = decodedToken.uid;
const customToken = await getAuth().createCustomToken(uid);If extracting UID from request parameters (query string, body, headers), ensure proper extraction and validation.
Incorrect - no extraction validation:
import { getAuth } from 'firebase-admin/auth';
import functions from 'firebase-functions';
// ❌ Doesn't validate uid parameter exists
exports.myFunction = functions.https.onRequest(async (req, res) => {
const uid = req.body.uid; // Could be undefined
const token = await getAuth().createCustomToken(uid); // Fails!
res.json({ token });
});Correct - validate extracted UID:
import { getAuth } from 'firebase-admin/auth';
import functions from 'firebase-functions';
exports.myFunction = functions.https.onRequest(async (req, res) => {
const uid = req.body?.uid;
// Validate UID parameter
if (!uid || typeof uid !== 'string') {
return res.status(400).json({
error: 'Missing or invalid uid parameter',
code: 'MISSING_UID'
});
}
try {
const token = await getAuth().createCustomToken(uid);
res.json({ token });
} catch (error: any) {
console.error('Error:', error.code);
res.status(500).json({ error: error.message });
}
});If using TypeScript, define proper types for user objects and use strict null checking.
Incorrect - loose typing:
import { getAuth } from 'firebase-admin/auth';
async function updateUserClaims(user: any) { // ❌ any type
// UID might be missing and TypeScript won't catch it
await getAuth().setCustomUserClaims(user.uid, { role: 'admin' });
}Correct - proper TypeScript types:
import { getAuth } from 'firebase-admin/auth';
interface UserData {
uid: string; // ✅ Required property
email?: string;
displayName?: string;
}
async function updateUserClaims(user: UserData, claims: Record<string, any>) {
// TypeScript ensures uid is present
if (!user.uid) {
throw new Error('User UID is required');
}
await getAuth().setCustomUserClaims(user.uid, claims);
}
// Usage
await updateUserClaims({ uid: 'user-123' }, { role: 'admin' });Enable strict null checking in tsconfig.json:
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true
}
}When troubleshooting, add logging to see what value is being passed.
Example debugging approach:
import { getAuth } from 'firebase-admin/auth';
async function createTokenWithDebug(uid: any) {
console.log('UID value:', uid);
console.log('UID type:', typeof uid);
console.log('UID length:', uid?.length || 'N/A');
console.log('Is UID truthy:', !!uid);
// Additional checks
if (uid === undefined) {
console.error('ERROR: uid is undefined');
throw new Error('auth/missing-uid: User ID identifier required');
}
if (uid === null) {
console.error('ERROR: uid is null');
throw new Error('auth/missing-uid: User ID identifier required');
}
if (uid === '') {
console.error('ERROR: uid is empty string');
throw new Error('auth/missing-uid: User ID identifier required');
}
if (typeof uid !== 'string') {
console.error('ERROR: uid is not a string, got:', typeof uid);
throw new Error('auth/missing-uid: User ID identifier required');
}
console.log('Creating custom token for UID:', uid);
const customToken = await getAuth().createCustomToken(uid);
return customToken;
}This debugging output helps identify exactly why the UID is missing or invalid.
Test your user management code with the Firebase Emulator Suite before deploying.
Setup emulator:
# Install Firebase CLI
npm install -g firebase-tools
# Start emulator
firebase emulators:start --only auth
# In another terminal, initialize Firebase with emulator
export FIREBASE_AUTH_EMULATOR_HOST=localhost:9099Test code with emulator:
import { getAuth } from 'firebase-admin/auth';
// When FIREBASE_AUTH_EMULATOR_HOST env var is set,
// Firebase Admin SDK connects to local emulator instead of production
async function testCreateCustomToken() {
try {
// This will use the emulator
const token = await getAuth().createCustomToken('test-user-123');
console.log('Success:', token);
} catch (error: any) {
console.error('Error:', error.code, error.message);
}
}
await testCreateCustomToken();The emulator properly validates and throws auth/missing-uid errors, helping you catch issues before production.
UID Format and Constraints:
Firebase UIDs must follow these rules:
- Must be a non-empty UTF-8 string
- Maximum length of 128 characters
- Must be unique across your entire Firebase project
- No validation of format (you can use custom IDs or auto-generated ones)
Common UID Sources:
When working with Firebase Authentication, UID comes from different places depending on context:
- Admin SDK: Explicitly pass the UID to functions
- Client SDK: Access from user.uid after authentication
- JWT tokens: Decode and access from decodedToken.uid
- Database: Store UID after user creation and retrieve for later operations
Error Handling Strategy:
Instead of just catching the error, implement proactive validation:
// Bad: Wait for error to happen
try {
await getAuth().createCustomToken(uid); // May throw auth/missing-uid
} catch (error: any) {
// Too late - request already failed
}
// Good: Validate before attempting
if (!uid || typeof uid !== 'string' || uid.trim() === '') {
throw new Error('Invalid UID: UID must be a non-empty string');
}
const token = await getAuth().createCustomToken(uid);Batch Operations:
When processing multiple users, validate each UID individually:
async function processBatch(userIds: (string | undefined | null)[]) {
const results = [];
for (const uid of userIds) {
if (!uid || typeof uid !== 'string') {
results.push({ uid, success: false, error: 'Invalid UID' });
continue;
}
try {
const token = await getAuth().createCustomToken(uid);
results.push({ uid, success: true, token });
} catch (error: any) {
results.push({ uid, success: false, error: error.message });
}
}
return results;
}messaging/UNSPECIFIED_ERROR: No additional information available
How to fix "messaging/UNSPECIFIED_ERROR: No additional information available" in Firebase Cloud Messaging
App Check: reCAPTCHA Score Too Low
App Check reCAPTCHA Score Too Low
storage/invalid-url: Invalid URL format for Cloud Storage reference
How to fix invalid URL format in Firebase Cloud Storage
auth/invalid-argument: Invalid parameter passed to method
How to fix "auth/invalid-argument: Invalid parameter passed to method" in Firebase
storage/invalid-argument: Incorrect data type passed to upload function
How to fix "storage/invalid-argument: Incorrect data type passed to upload" in Firebase Storage