Firebase
Mobile Platform
Firebase
Overview
Firebase is Google's comprehensive mobile and web application development platform, providing Backend as a Service (BaaS) with real-time databases, authentication, cloud functions, and analytics in a unified ecosystem. Since Google's acquisition, it has evolved beyond simple BaaS to become a complete application development platform supporting the entire development lifecycle from prototyping to production scaling. As of 2025, with advanced AI/ML integrations, enhanced security features, improved performance, and expanded multi-platform support, Firebase has established itself as the industry standard for rapid application development and reliable cloud infrastructure.
Details
Firebase 2025 edition provides a comprehensive development platform that goes beyond traditional Backend as a Service, offering deep integration with Google Cloud Platform and advanced AI capabilities. Particularly noteworthy are the new AI-powered development assistance features, enhanced Firestore query capabilities, improved Cloud Functions performance, and strengthened security rules. With seamless integration across iOS, Android, Web, Flutter, React Native, and Unity platforms, real-time synchronization, automatic scaling, and rich analytics capabilities, it provides everything needed for modern application development.
Key Features
- Real-time Database: NoSQL cloud database with real-time synchronization
- Authentication: Comprehensive user authentication and authorization
- Cloud Functions: Serverless backend logic execution
- Cloud Storage: Scalable file and media storage
- Analytics: Advanced user behavior analysis and performance monitoring
- Crashlytics: Real-time crash reporting and analysis
Latest 2025 Features
- AI-powered Development: Code generation and optimization assistance
- Enhanced Firestore: Improved query performance and new data types
- Advanced Security Rules: ML-based threat detection and prevention
- Multi-platform SDK: Unified development experience across all platforms
- Performance Improvements: Faster cold starts and reduced latency
- Extended Integrations: Deep integration with Google Cloud AI services
Advantages and Disadvantages
Advantages
- Comprehensive development platform with everything needed for app development
- Real-time data synchronization and excellent user experience
- Automatic scaling and high availability infrastructure
- Rich authentication options and security features
- Extensive multi-platform support and unified development experience
- Deep integration with Google services and ecosystem
- Generous free tier and transparent pricing structure
Disadvantages
- Vendor lock-in to Google ecosystem
- Complex pricing structure can become expensive at scale
- Limited customization options for backend logic
- NoSQL database limitations for complex relational queries
- Dependency on Google Cloud Platform stability
- Learning curve for comprehensive feature set
- Potential data sovereignty concerns in certain regions
Reference Pages
Code Examples
Setup and Basic Configuration
# Install Firebase CLI
npm install -g firebase-tools
# Login to Firebase account
firebase login
# Initialize Firebase project
firebase init
# Install Firebase SDK (React Native)
npm install @react-native-firebase/app
# Install additional modules
npm install @react-native-firebase/auth
npm install @react-native-firebase/firestore
npm install @react-native-firebase/storage
npm install @react-native-firebase/functions
npm install @react-native-firebase/analytics
# iOS specific setup (for React Native)
cd ios && pod install
// firebase.config.ts - Firebase Configuration
import { initializeApp, getApps } from '@react-native-firebase/app';
import auth from '@react-native-firebase/auth';
import firestore from '@react-native-firebase/firestore';
import storage from '@react-native-firebase/storage';
import functions from '@react-native-firebase/functions';
import analytics from '@react-native-firebase/analytics';
// Firebase configuration
const firebaseConfig = {
apiKey: "your-api-key",
authDomain: "your-project.firebaseapp.com",
projectId: "your-project-id",
storageBucket: "your-project.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:android:abcdef123456",
measurementId: "G-XXXXXXXXXX"
};
// Initialize Firebase (prevent multiple initialization)
if (getApps().length === 0) {
initializeApp(firebaseConfig);
}
// Export Firebase services
export {
auth,
firestore,
storage,
functions,
analytics
};
// Service initialization check
export const checkFirebaseServices = async () => {
try {
// Check Authentication service
const authUser = auth().currentUser;
console.log('Auth service initialized:', !!auth());
// Check Firestore service
await firestore().enableNetwork();
console.log('Firestore service initialized');
// Check Storage service
const storageRef = storage().ref();
console.log('Storage service initialized:', !!storageRef);
// Check Functions service
const functionsInstance = functions();
console.log('Functions service initialized:', !!functionsInstance);
return true;
} catch (error) {
console.error('Firebase service initialization error:', error);
return false;
}
};
Authentication and User Management
// authService.ts - Complete Authentication Service
import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-google-signin/google-signin';
import { firestore } from './firebase.config';
// Configure Google Sign-In
GoogleSignin.configure({
webClientId: 'your-web-client-id.googleusercontent.com',
});
export interface User {
uid: string;
email: string;
displayName: string;
photoURL?: string;
emailVerified: boolean;
createdAt: Date;
lastLoginAt: Date;
}
export class AuthService {
// Email/Password Registration
static async registerWithEmail(email: string, password: string, displayName: string): Promise<User | null> {
try {
const userCredential = await auth().createUserWithEmailAndPassword(email, password);
const user = userCredential.user;
// Update user profile
await user.updateProfile({
displayName: displayName
});
// Send email verification
await user.sendEmailVerification();
// Create user document in Firestore
const userData: User = {
uid: user.uid,
email: user.email!,
displayName: displayName,
photoURL: user.photoURL || undefined,
emailVerified: user.emailVerified,
createdAt: new Date(),
lastLoginAt: new Date()
};
await firestore().collection('users').doc(user.uid).set(userData);
return userData;
} catch (error) {
console.error('Registration error:', error);
throw error;
}
}
// Email/Password Login
static async loginWithEmail(email: string, password: string): Promise<User | null> {
try {
const userCredential = await auth().signInWithEmailAndPassword(email, password);
const user = userCredential.user;
// Update last login time
await firestore().collection('users').doc(user.uid).update({
lastLoginAt: new Date()
});
return await this.getCurrentUser();
} catch (error) {
console.error('Login error:', error);
throw error;
}
}
// Google Sign-In
static async loginWithGoogle(): Promise<User | null> {
try {
// Check if your device supports Google Play
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
// Get the user's ID token
const { idToken } = await GoogleSignin.signIn();
// Create a Google credential with the token
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
// Sign-in the user with the credential
const userCredential = await auth().signInWithCredential(googleCredential);
const user = userCredential.user;
// Create or update user document
const userData: User = {
uid: user.uid,
email: user.email!,
displayName: user.displayName!,
photoURL: user.photoURL || undefined,
emailVerified: user.emailVerified,
createdAt: new Date(),
lastLoginAt: new Date()
};
await firestore().collection('users').doc(user.uid).set(userData, { merge: true });
return userData;
} catch (error) {
console.error('Google sign-in error:', error);
throw error;
}
}
// Get current user
static async getCurrentUser(): Promise<User | null> {
try {
const firebaseUser = auth().currentUser;
if (!firebaseUser) return null;
const userDoc = await firestore().collection('users').doc(firebaseUser.uid).get();
if (userDoc.exists) {
return userDoc.data() as User;
}
return null;
} catch (error) {
console.error('Get current user error:', error);
return null;
}
}
// Password Reset
static async resetPassword(email: string): Promise<void> {
try {
await auth().sendPasswordResetEmail(email);
} catch (error) {
console.error('Password reset error:', error);
throw error;
}
}
// Sign Out
static async signOut(): Promise<void> {
try {
await GoogleSignin.signOut();
await auth().signOut();
} catch (error) {
console.error('Sign out error:', error);
throw error;
}
}
// Delete Account
static async deleteAccount(): Promise<void> {
try {
const user = auth().currentUser;
if (!user) throw new Error('No user logged in');
// Delete user document from Firestore
await firestore().collection('users').doc(user.uid).delete();
// Delete Firebase Auth user
await user.delete();
} catch (error) {
console.error('Delete account error:', error);
throw error;
}
}
}
// Authentication state listener
export const useAuthState = (callback: (user: User | null) => void) => {
return auth().onAuthStateChanged(async (firebaseUser) => {
if (firebaseUser) {
const user = await AuthService.getCurrentUser();
callback(user);
} else {
callback(null);
}
});
};
Backend Integration and Real-time Data
// firestoreService.ts - Firestore Database Service
import firestore, { FirebaseFirestoreTypes } from '@react-native-firebase/firestore';
export interface Post {
id?: string;
title: string;
content: string;
authorId: string;
authorName: string;
createdAt: Date;
updatedAt: Date;
likes: number;
tags: string[];
published: boolean;
}
export interface Comment {
id?: string;
postId: string;
authorId: string;
authorName: string;
content: string;
createdAt: Date;
likes: number;
}
export class FirestoreService {
// Posts collection operations
static async createPost(postData: Omit<Post, 'id' | 'createdAt' | 'updatedAt'>): Promise<string> {
try {
const post: Post = {
...postData,
createdAt: new Date(),
updatedAt: new Date()
};
const docRef = await firestore().collection('posts').add(post);
return docRef.id;
} catch (error) {
console.error('Create post error:', error);
throw error;
}
}
static async updatePost(postId: string, updates: Partial<Post>): Promise<void> {
try {
await firestore().collection('posts').doc(postId).update({
...updates,
updatedAt: new Date()
});
} catch (error) {
console.error('Update post error:', error);
throw error;
}
}
static async deletePost(postId: string): Promise<void> {
try {
const batch = firestore().batch();
// Delete post
batch.delete(firestore().collection('posts').doc(postId));
// Delete all comments for this post
const commentsSnapshot = await firestore()
.collection('comments')
.where('postId', '==', postId)
.get();
commentsSnapshot.docs.forEach(doc => {
batch.delete(doc.ref);
});
await batch.commit();
} catch (error) {
console.error('Delete post error:', error);
throw error;
}
}
// Real-time posts listener
static listenToPosts(callback: (posts: Post[]) => void): () => void {
return firestore()
.collection('posts')
.where('published', '==', true)
.orderBy('createdAt', 'desc')
.onSnapshot(
(snapshot) => {
const posts: Post[] = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
} as Post));
callback(posts);
},
(error) => {
console.error('Posts listener error:', error);
}
);
}
// Comments operations
static async addComment(commentData: Omit<Comment, 'id' | 'createdAt'>): Promise<string> {
try {
const comment: Comment = {
...commentData,
createdAt: new Date()
};
const docRef = await firestore().collection('comments').add(comment);
// Update post comment count (using transaction for consistency)
await firestore().runTransaction(async (transaction) => {
const postRef = firestore().collection('posts').doc(comment.postId);
const postDoc = await transaction.get(postRef);
if (postDoc.exists) {
const currentCommentCount = postDoc.data()?.commentCount || 0;
transaction.update(postRef, {
commentCount: currentCommentCount + 1
});
}
});
return docRef.id;
} catch (error) {
console.error('Add comment error:', error);
throw error;
}
}
// Real-time comments listener
static listenToComments(postId: string, callback: (comments: Comment[]) => void): () => void {
return firestore()
.collection('comments')
.where('postId', '==', postId)
.orderBy('createdAt', 'asc')
.onSnapshot(
(snapshot) => {
const comments: Comment[] = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
} as Comment));
callback(comments);
},
(error) => {
console.error('Comments listener error:', error);
}
);
}
// Advanced queries with pagination
static async getPostsPaginated(
lastDocument?: FirebaseFirestoreTypes.QueryDocumentSnapshot,
limit: number = 10
): Promise<{ posts: Post[]; lastDocument?: FirebaseFirestoreTypes.QueryDocumentSnapshot }> {
try {
let query = firestore()
.collection('posts')
.where('published', '==', true)
.orderBy('createdAt', 'desc')
.limit(limit);
if (lastDocument) {
query = query.startAfter(lastDocument);
}
const snapshot = await query.get();
const posts: Post[] = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
} as Post));
return {
posts,
lastDocument: snapshot.docs[snapshot.docs.length - 1]
};
} catch (error) {
console.error('Get paginated posts error:', error);
throw error;
}
}
// Search posts by tags
static async searchPostsByTags(tags: string[]): Promise<Post[]> {
try {
const snapshot = await firestore()
.collection('posts')
.where('tags', 'array-contains-any', tags)
.where('published', '==', true)
.orderBy('createdAt', 'desc')
.get();
return snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
} as Post));
} catch (error) {
console.error('Search posts error:', error);
throw error;
}
}
}
Push Notifications and Messaging
// notificationService.ts - Firebase Cloud Messaging Service
import messaging from '@react-native-firebase/messaging';
import { PermissionsAndroid, Platform } from 'react-native';
import PushNotification from 'react-native-push-notification';
import { firestore } from './firebase.config';
export interface NotificationData {
title: string;
body: string;
data?: { [key: string]: string };
userId?: string;
topic?: string;
}
export class NotificationService {
// Initialize FCM
static async initialize(): Promise<void> {
try {
// Request permission (iOS)
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (!enabled) {
console.log('Push notification permission denied');
return;
}
// Request permission (Android)
if (Platform.OS === 'android') {
await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
}
// Configure local notifications
PushNotification.configure({
onNotification: function (notification) {
console.log('Local notification received:', notification);
},
requestPermissions: Platform.OS === 'ios',
});
// Get FCM token
const token = await messaging().getToken();
console.log('FCM Token:', token);
// Save token to Firestore for current user
await this.saveFCMToken(token);
// Listen for token refresh
messaging().onTokenRefresh(async (newToken) => {
console.log('FCM Token refreshed:', newToken);
await this.saveFCMToken(newToken);
});
// Handle foreground messages
messaging().onMessage(async (remoteMessage) => {
console.log('Foreground message received:', remoteMessage);
this.displayLocalNotification(remoteMessage);
});
// Handle background/quit state messages
messaging().onNotificationOpenedApp((remoteMessage) => {
console.log('Notification opened app:', remoteMessage);
this.handleNotificationAction(remoteMessage);
});
// Handle app opened from notification (cold start)
const initialNotification = await messaging().getInitialNotification();
if (initialNotification) {
console.log('App opened from notification:', initialNotification);
this.handleNotificationAction(initialNotification);
}
} catch (error) {
console.error('FCM initialization error:', error);
}
}
// Save FCM token to Firestore
static async saveFCMToken(token: string): Promise<void> {
try {
const userId = 'current-user-id'; // Get from auth service
await firestore().collection('users').doc(userId).update({
fcmTokens: firestore.FieldValue.arrayUnion(token),
lastTokenUpdate: new Date()
});
} catch (error) {
console.error('Save FCM token error:', error);
}
}
// Display local notification for foreground messages
static displayLocalNotification(remoteMessage: any): void {
PushNotification.localNotification({
title: remoteMessage.notification?.title || 'New Message',
message: remoteMessage.notification?.body || 'You have a new message',
playSound: true,
soundName: 'default',
userInfo: remoteMessage.data,
});
}
// Handle notification action
static handleNotificationAction(remoteMessage: any): void {
const { data } = remoteMessage;
if (data?.screen) {
// Navigate to specific screen
console.log('Navigate to screen:', data.screen);
// Implement navigation logic here
}
if (data?.action) {
// Handle specific actions
console.log('Handle action:', data.action);
// Implement action handling logic here
}
}
// Subscribe to topic
static async subscribeToTopic(topic: string): Promise<void> {
try {
await messaging().subscribeToTopic(topic);
console.log(`Subscribed to topic: ${topic}`);
} catch (error) {
console.error('Subscribe to topic error:', error);
}
}
// Unsubscribe from topic
static async unsubscribeFromTopic(topic: string): Promise<void> {
try {
await messaging().unsubscribeFromTopic(topic);
console.log(`Unsubscribed from topic: ${topic}`);
} catch (error) {
console.error('Unsubscribe from topic error:', error);
}
}
// Send notification via Cloud Function
static async sendNotification(notificationData: NotificationData): Promise<void> {
try {
const functions = require('@react-native-firebase/functions').default;
const sendNotificationFunction = functions().httpsCallable('sendNotification');
const result = await sendNotificationFunction(notificationData);
console.log('Notification sent successfully:', result.data);
} catch (error) {
console.error('Send notification error:', error);
throw error;
}
}
// Schedule local notification
static scheduleLocalNotification(
title: string,
message: string,
date: Date,
data?: { [key: string]: any }
): void {
PushNotification.localNotificationSchedule({
title,
message,
date,
userInfo: data,
playSound: true,
soundName: 'default',
});
}
// Cancel all local notifications
static cancelAllLocalNotifications(): void {
PushNotification.cancelAllLocalNotifications();
}
// Get notification permissions status
static async getPermissionStatus(): Promise<string> {
const authStatus = await messaging().requestPermission();
switch (authStatus) {
case messaging.AuthorizationStatus.AUTHORIZED:
return 'authorized';
case messaging.AuthorizationStatus.DENIED:
return 'denied';
case messaging.AuthorizationStatus.NOT_DETERMINED:
return 'not_determined';
case messaging.AuthorizationStatus.PROVISIONAL:
return 'provisional';
default:
return 'unknown';
}
}
}
// Cloud Function for sending notifications (deploy this to Firebase)
/*
// functions/src/index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
export const sendNotification = functions.https.onCall(async (data, context) => {
const { title, body, userId, topic, data: customData } = data;
try {
let message: admin.messaging.Message;
if (userId) {
// Send to specific user
const userDoc = await admin.firestore().collection('users').doc(userId).get();
const userData = userDoc.data();
const fcmTokens = userData?.fcmTokens || [];
if (fcmTokens.length === 0) {
throw new Error('No FCM tokens found for user');
}
message = {
notification: { title, body },
data: customData || {},
tokens: fcmTokens,
};
const response = await admin.messaging().sendMulticast(message);
return { success: true, response };
} else if (topic) {
// Send to topic
message = {
notification: { title, body },
data: customData || {},
topic,
};
const response = await admin.messaging().send(message);
return { success: true, messageId: response };
}
throw new Error('Either userId or topic must be provided');
} catch (error) {
console.error('Send notification error:', error);
throw new functions.https.HttpsError('internal', error.message);
}
});
*/
Analytics and Performance Monitoring
// analyticsService.ts - Firebase Analytics Service
import analytics from '@react-native-firebase/analytics';
import crashlytics from '@react-native-firebase/crashlytics';
import perf from '@react-native-firebase/perf';
export interface AnalyticsEvent {
name: string;
parameters?: { [key: string]: any };
}
export interface UserProperties {
[key: string]: string | number | boolean;
}
export class AnalyticsService {
// Initialize Analytics
static async initialize(): Promise<void> {
try {
// Enable analytics collection
await analytics().setAnalyticsCollectionEnabled(true);
// Enable crashlytics collection
await crashlytics().setCrashlyticsCollectionEnabled(true);
console.log('Analytics services initialized');
} catch (error) {
console.error('Analytics initialization error:', error);
}
}
// Track custom events
static async trackEvent(eventName: string, parameters?: { [key: string]: any }): Promise<void> {
try {
await analytics().logEvent(eventName, parameters);
console.log(`Event tracked: ${eventName}`, parameters);
} catch (error) {
console.error('Track event error:', error);
}
}
// Track screen views
static async trackScreenView(screenName: string, screenClass?: string): Promise<void> {
try {
await analytics().logScreenView({
screen_name: screenName,
screen_class: screenClass || screenName,
});
console.log(`Screen view tracked: ${screenName}`);
} catch (error) {
console.error('Track screen view error:', error);
}
}
// Set user properties
static async setUserProperties(properties: UserProperties): Promise<void> {
try {
for (const [key, value] of Object.entries(properties)) {
await analytics().setUserProperty(key, String(value));
}
console.log('User properties set:', properties);
} catch (error) {
console.error('Set user properties error:', error);
}
}
// Set user ID
static async setUserId(userId: string): Promise<void> {
try {
await analytics().setUserId(userId);
await crashlytics().setUserId(userId);
console.log(`User ID set: ${userId}`);
} catch (error) {
console.error('Set user ID error:', error);
}
}
// Track e-commerce events
static async trackPurchase(transactionId: string, value: number, currency: string, items: any[]): Promise<void> {
try {
await analytics().logEvent('purchase', {
transaction_id: transactionId,
value,
currency,
items,
});
// Also track individual items
for (const item of items) {
await analytics().logEvent('select_item', {
item_id: item.item_id,
item_name: item.item_name,
item_category: item.item_category,
value: item.price,
currency,
});
}
console.log('Purchase tracked:', { transactionId, value, currency });
} catch (error) {
console.error('Track purchase error:', error);
}
}
// Track user engagement
static async trackUserEngagement(action: string, duration?: number): Promise<void> {
try {
const parameters: { [key: string]: any } = { action };
if (duration !== undefined) {
parameters.engagement_time_msec = duration;
}
await analytics().logEvent('user_engagement', parameters);
console.log('User engagement tracked:', parameters);
} catch (error) {
console.error('Track user engagement error:', error);
}
}
// Performance monitoring
static async startPerformanceTrace(traceName: string): Promise<any> {
try {
const trace = perf().newTrace(traceName);
await trace.start();
console.log(`Performance trace started: ${traceName}`);
return trace;
} catch (error) {
console.error('Start performance trace error:', error);
return null;
}
}
static async stopPerformanceTrace(trace: any, attributes?: { [key: string]: string }): Promise<void> {
try {
if (attributes) {
for (const [key, value] of Object.entries(attributes)) {
trace.putAttribute(key, value);
}
}
await trace.stop();
console.log('Performance trace stopped');
} catch (error) {
console.error('Stop performance trace error:', error);
}
}
// Crashlytics error reporting
static recordError(error: Error, additionalInfo?: { [key: string]: any }): void {
try {
if (additionalInfo) {
for (const [key, value] of Object.entries(additionalInfo)) {
crashlytics().setAttribute(key, String(value));
}
}
crashlytics().recordError(error);
console.log('Error recorded to Crashlytics:', error.message);
} catch (err) {
console.error('Record error to Crashlytics failed:', err);
}
}
// Custom log for debugging
static log(message: string, level: 'debug' | 'info' | 'warning' | 'error' = 'info'): void {
try {
crashlytics().log(`[${level.toUpperCase()}] ${message}`);
console.log(`Crashlytics log: ${message}`);
} catch (error) {
console.error('Crashlytics log error:', error);
}
}
// Set custom keys for crash reports
static setCustomKeys(keys: { [key: string]: any }): void {
try {
for (const [key, value] of Object.entries(keys)) {
if (typeof value === 'string') {
crashlytics().setAttribute(key, value);
} else if (typeof value === 'number') {
crashlytics().setAttribute(key, value.toString());
} else if (typeof value === 'boolean') {
crashlytics().setAttribute(key, value.toString());
}
}
console.log('Custom keys set for crash reports:', keys);
} catch (error) {
console.error('Set custom keys error:', error);
}
}
// Test crash (development only)
static testCrash(): void {
if (__DEV__) {
crashlytics().crash();
}
}
}
// Performance monitoring utilities
export class PerformanceMonitor {
private static traces: Map<string, any> = new Map();
static async startTrace(name: string): Promise<void> {
try {
const trace = perf().newTrace(name);
await trace.start();
this.traces.set(name, trace);
} catch (error) {
console.error(`Start trace ${name} error:`, error);
}
}
static async stopTrace(name: string, metrics?: { [key: string]: number }): Promise<void> {
try {
const trace = this.traces.get(name);
if (trace) {
if (metrics) {
for (const [key, value] of Object.entries(metrics)) {
trace.putMetric(key, value);
}
}
await trace.stop();
this.traces.delete(name);
}
} catch (error) {
console.error(`Stop trace ${name} error:`, error);
}
}
static async measureAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {
await this.startTrace(name);
try {
const result = await fn();
await this.stopTrace(name);
return result;
} catch (error) {
await this.stopTrace(name);
throw error;
}
}
}
Deployment and Configuration
// deployment.ts - Firebase Deployment and Configuration
import { firestore, storage, functions } from './firebase.config';
export interface DeploymentConfig {
environment: 'development' | 'staging' | 'production';
version: string;
features: string[];
securityRules: any;
}
export class FirebaseDeployment {
// Environment-specific configuration
static getEnvironmentConfig(): DeploymentConfig {
const environment = __DEV__ ? 'development' : 'production';
const configs: { [key: string]: DeploymentConfig } = {
development: {
environment: 'development',
version: '1.0.0-dev',
features: ['debug_mode', 'test_data'],
securityRules: {
strict: false,
allowTestData: true
}
},
staging: {
environment: 'staging',
version: '1.0.0-rc',
features: ['beta_features'],
securityRules: {
strict: true,
allowTestData: false
}
},
production: {
environment: 'production',
version: '1.0.0',
features: ['production_features'],
securityRules: {
strict: true,
allowTestData: false
}
}
};
return configs[environment];
}
// Database initialization with sample data
static async initializeDatabase(): Promise<void> {
try {
const config = this.getEnvironmentConfig();
// Create initial collections and documents
const batch = firestore().batch();
// App configuration document
const appConfigRef = firestore().collection('config').doc('app');
batch.set(appConfigRef, {
version: config.version,
environment: config.environment,
features: config.features,
maintenanceMode: false,
lastUpdated: new Date()
});
// Default user roles
const rolesRef = firestore().collection('config').doc('roles');
batch.set(rolesRef, {
admin: {
permissions: ['read', 'write', 'delete', 'manage_users'],
level: 100
},
moderator: {
permissions: ['read', 'write', 'moderate_content'],
level: 50
},
user: {
permissions: ['read', 'write_own'],
level: 10
}
});
// Sample data for development
if (config.environment === 'development') {
const samplePostRef = firestore().collection('posts').doc();
batch.set(samplePostRef, {
title: 'Welcome to Firebase',
content: 'This is a sample post to demonstrate Firebase functionality.',
authorId: 'sample-user-id',
authorName: 'Sample User',
createdAt: new Date(),
updatedAt: new Date(),
likes: 0,
tags: ['firebase', 'react-native', 'mobile'],
published: true
});
}
await batch.commit();
console.log('Database initialized successfully');
} catch (error) {
console.error('Database initialization error:', error);
throw error;
}
}
// Storage setup and file organization
static async setupStorage(): Promise<void> {
try {
const config = this.getEnvironmentConfig();
// Create storage structure
const storageRef = storage().ref();
// Create directory structure by uploading placeholder files
const directories = [
'users/avatars',
'posts/images',
'posts/videos',
'uploads/temp',
'system/backups'
];
for (const dir of directories) {
const placeholder = `${dir}/.placeholder`;
const placeholderRef = storageRef.child(placeholder);
try {
await placeholderRef.putString('# Placeholder file for directory structure', 'raw', {
contentType: 'text/plain'
});
} catch (error) {
// Directory might already exist
console.log(`Directory ${dir} already exists or creation skipped`);
}
}
console.log('Storage structure created successfully');
} catch (error) {
console.error('Storage setup error:', error);
throw error;
}
}
// Cloud Functions deployment check
static async checkCloudFunctions(): Promise<boolean> {
try {
const testFunction = functions().httpsCallable('healthCheck');
const result = await testFunction();
if (result.data?.status === 'ok') {
console.log('Cloud Functions are healthy');
return true;
} else {
console.warn('Cloud Functions health check failed');
return false;
}
} catch (error) {
console.error('Cloud Functions check error:', error);
return false;
}
}
// Security rules validation
static async validateSecurityRules(): Promise<boolean> {
try {
// Test read/write permissions for current user
const testDoc = firestore().collection('_test').doc('security-test');
// Test write
await testDoc.set({
test: true,
timestamp: new Date()
});
// Test read
const doc = await testDoc.get();
// Cleanup
await testDoc.delete();
if (doc.exists) {
console.log('Security rules validation passed');
return true;
} else {
console.warn('Security rules validation failed');
return false;
}
} catch (error) {
console.error('Security rules validation error:', error);
return false;
}
}
// Complete deployment verification
static async verifyDeployment(): Promise<{ [key: string]: boolean }> {
const results = {
database: false,
storage: false,
functions: false,
security: false
};
try {
// Initialize database
await this.initializeDatabase();
results.database = true;
// Setup storage
await this.setupStorage();
results.storage = true;
// Check functions
results.functions = await this.checkCloudFunctions();
// Validate security
results.security = await this.validateSecurityRules();
const allPassed = Object.values(results).every(result => result);
console.log('Deployment verification results:', results);
console.log(`Deployment ${allPassed ? 'PASSED' : 'FAILED'}`);
return results;
} catch (error) {
console.error('Deployment verification error:', error);
return results;
}
}
}
// Deployment scripts
export const deploymentScripts = {
// Development setup
async setupDevelopment(): Promise<void> {
console.log('Setting up development environment...');
await FirebaseDeployment.verifyDeployment();
},
// Production deployment
async deployProduction(): Promise<void> {
console.log('Deploying to production...');
const results = await FirebaseDeployment.verifyDeployment();
if (!Object.values(results).every(result => result)) {
throw new Error('Production deployment failed verification');
}
console.log('Production deployment successful');
},
// Health check
async healthCheck(): Promise<boolean> {
const results = await FirebaseDeployment.verifyDeployment();
return Object.values(results).every(result => result);
}
};