Firebase returns a service unavailable error when it cannot process your request, typically due to temporary service disruptions, network connectivity issues, or device offline conditions with no cached data. This is usually a transient error that can be resolved by implementing retry logic with exponential backoff.
The "UNAVAILABLE: The service is currently unavailable" error (gRPC status code 14) occurs when Firebase services (Firestore, Cloud Functions, Realtime Database, or other APIs) cannot respond to your request. This is a transient error meaning the service may be temporarily unavailable and may recover automatically. The error message suggests that this condition is temporary and may be corrected by retrying with exponential backoff. The error can occur in several contexts: Firestore queries or writes timing out, Cloud Functions failing to deploy or execute, device being offline with no locally cached data, network connectivity issues between your application and Firebase backends, or temporary Firebase service disruptions or maintenance.
Before investigating further, verify whether Firebase is experiencing a known outage or maintenance window:
1. Visit the [Firebase Status Dashboard](https://status.firebase.google.com/)
2. Check for any red indicators or maintenance notices
3. Look specifically for your affected service (Firestore, Cloud Functions, etc.)
4. If there's an active incident, you may need to wait for Firebase to resolve it
If there's a known outage, your best option is to wait and retry your request after a few minutes.
The error message explicitly suggests retrying is the solution. Implement exponential backoff to handle transient failures:
// Node.js / JavaScript example
async function firestoreQueryWithRetry(query, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await query();
} catch (error) {
if (error.code === 'unavailable' && attempt < maxRetries) {
// Exponential backoff: 1s, 2s, 4s, etc.
const delayMs = Math.pow(2, attempt - 1) * 1000;
console.log(`Retrying in ${delayMs}ms (attempt ${attempt}/${maxRetries})`);
await new Promise(resolve => setTimeout(resolve, delayMs));
} else {
throw error; // Max retries or different error
}
}
}
}
// Usage
const result = await firestoreQueryWithRetry(() =>
db.collection('users').doc('userId').get()
);// Flutter / Dart example
Future<T> retryWithBackoff<T>(Future<T> Function() operation, {int maxRetries = 3}) async {
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (e) {
if (e is FirebaseException && e.code == 'unavailable' && attempt < maxRetries) {
final delayMs = (pow(2, attempt - 1) * 1000).toInt();
print('Retrying in ${delayMs}ms (attempt $attempt/$maxRetries)');
await Future.delayed(Duration(milliseconds: delayMs));
} else {
rethrow;
}
}
}
}
// Usage
final doc = await retryWithBackoff(() =>
FirebaseFirestore.instance.collection('users').doc('userId').get()
);// Android / Kotlin example
suspend fun <T> firestoreQueryWithRetry(
maxRetries: Int = 3,
query: suspend () -> T
): T {
repeat(maxRetries) { attempt ->
try {
return query()
} catch (e: FirebaseFirestoreException) {
if (e.code == FirebaseFirestoreException.Code.UNAVAILABLE && attempt < maxRetries - 1) {
val delayMs = (2.0.pow(attempt.toDouble()) * 1000).toLong()
Log.d("Firestore", "Retrying in ${delayMs}ms (attempt ${attempt + 1}/$maxRetries)")
delay(delayMs)
} else {
throw e
}
}
}
throw IllegalStateException("Retry loop failed")
}
// Usage
val doc = firestoreQueryWithRetry {
FirebaseFirestore.getInstance()
.collection("users")
.document("userId")
.get()
.await()
}The error often indicates network issues. Check that your device/application has a stable connection:
For web applications:
// Check if browser is online
if (!navigator.onLine) {
console.error('Device is offline');
// Show user an offline message
}
// Listen for connection changes
window.addEventListener('online', () => {
console.log('Connection restored, retrying...');
// Retry your operation
});
window.addEventListener('offline', () => {
console.log('Connection lost');
});For mobile apps:
- Android: Check network connectivity using ConnectivityManager
- iOS: Use Network framework or Reachability to monitor connection state
- Flutter: Use connectivity_plus package to check network status
For backend services:
# Verify network connectivity
ping google.com
# Check DNS resolution
nslookup firebaseio.com
# Verify no proxies/firewalls blocking Firebase
curl -v https://firestore.googleapis.com/If you're testing with Firestore emulator, ensure it's properly configured. A misconfigured emulator environment can cause unavailable errors:
# Remove or check the emulator host variable
echo $FIRESTORE_EMULATOR_HOST
# If set, verify the emulator is actually running on that host:port
# Default is usually localhost:8080
nc -zv localhost 8080
# If emulator is NOT running, either start it:
firebase emulators:start
# Or unset the environment variable for production:
unset FIRESTORE_EMULATOR_HOSTIn your code, ensure you're not accidentally connecting to the emulator in production:
// Check environment
if (process.env.FIRESTORE_EMULATOR_HOST) {
console.warn('Using Firestore emulator at', process.env.FIRESTORE_EMULATOR_HOST);
// Only should be true in development/testing
}If you're getting "service unavailable" during Cloud Functions deployment:
# Check the detailed deployment logs
firebase deploy --only functions --debug
# Deploy to a specific region if having issues
firebase deploy --only functions --region us-central1
# If deployment keeps failing, try again after a few minutes
# or check the Cloud Service Health dashboardIf deployment consistently fails:
1. Check [Cloud Service Health](https://cloud.google.com/status)
2. Try deploying to a different region
3. Split your functions into smaller deployments (some users report success with this)
4. Contact Firebase Support with your project ID and deployment logs
Sometimes the error is related to outdated or incompatible libraries. Ensure your Firebase dependencies are current:
# JavaScript/Node.js - update Firebase SDK
npm install --save firebase@latest
npm install --save firebase-admin@latest
# Flutter - update cloud_firestore
flutter pub upgrade cloud_firestore
# Android - update via Gradle or Android Studio dependency management
# Check build.gradle for com.google.firebase:firebase-firestore version
# iOS - update via CocoaPods
pod update FirebaseFor Node.js specifically, ensure you're using the correct gRPC implementation:
npm list grpc @grpc/grpc-js
# Modern versions should use @grpc/grpc-js (not the older 'grpc' package)
# Update if needed:
npm install --save @grpc/grpc-jsTransient vs Persistent Errors: The error message explicitly states "This is a most likely a transient condition." This means Firebase is telling you that the issue is probably temporary. Persistent unavailability errors that don't resolve with retries usually indicate a problem beyond normal operation (e.g., account suspension, quota exceeded, or actual outage).
gRPC Status Code 14: This error comes from the gRPC protocol layer that Firebase uses internally. The code "14 UNAVAILABLE" is a standard gRPC error indicating the service is not currently available. Unlike HTTP 503 which has clearer semantics, gRPC 14 can indicate various connectivity issues.
Battery Optimization and Background App Limits: On mobile devices (especially Android 10+), battery optimization can aggressively kill background network connections. If users report this error when your app is backgrounded:
- Educate users to whitelist your app in battery settings
- Use foreground services if keeping real-time connections is critical
- Implement background sync that gracefully handles connection failures
Offline-First Architecture: For better resilience, implement Firestore's offline persistence:
- JavaScript: Enable offline persistence with enablePersistence()
- Flutter: Default persistence is enabled
- Android/iOS: Built-in offline support available
When offline with no cached data, Firestore returns UNAVAILABLE, which your retry logic should handle by checking online status first.
Rate Limiting and Quotas: In rare cases, UNAVAILABLE can indicate you've hit rate limits or quota restrictions. Check your Firebase billing plan and current usage:
1. Open Firebase Console
2. Go to Firestore > Usage
3. Check if you're near any quota limits
4. Upgrade to Blaze plan if on Spark plan with usage restrictions
Callable Functions: INTERNAL - Unhandled exception
How to fix "Callable Functions: INTERNAL - Unhandled exception" in Firebase
auth/invalid-hash-algorithm: Hash algorithm doesn't match supported options
How to fix "auth/invalid-hash-algorithm: Hash algorithm doesn't match supported options" in Firebase
Hosting: CORS configuration not set up properly
How to fix CORS configuration in Firebase Hosting
auth/reserved-claims: Custom claims use reserved OIDC claim names
How to fix "reserved claims" error when setting custom claims in Firebase
Callable Functions: UNAUTHENTICATED - Invalid credentials
How to fix "UNAUTHENTICATED - Invalid credentials" in Firebase Callable Functions