Amba-Agent-App/lib/firebase/firebase.native.ts
2026-01-16 00:22:35 +03:00

201 lines
5.7 KiB
TypeScript

/**
* Firebase Native Implementation
* Uses @react-native-firebase for Android/iOS
*/
import { Platform } from "react-native";
import auth, { FirebaseAuthTypes } from "@react-native-firebase/auth";
import firestore from "@react-native-firebase/firestore";
import messaging from "@react-native-firebase/messaging";
import functions from "@react-native-firebase/functions";
import {
GoogleSignin,
statusCodes,
} from "@react-native-google-signin/google-signin";
// Web Client ID from google-services.json
const WEB_CLIENT_ID =
"613864011564-78d915g0hm9sbveskkfcch6mrd8atktb.apps.googleusercontent.com";
// iOS Client ID from GoogleService-Info.plist
const IOS_CLIENT_ID =
"613864011564-atsg9nau8hicla4td6dedcab15g7qr04.apps.googleusercontent.com";
// Configure Google Sign-In for native
GoogleSignin.configure({
webClientId: WEB_CLIENT_ID,
iosClientId: Platform.OS === "ios" ? IOS_CLIENT_ID : undefined,
offlineAccess: true,
});
// Export types
export type { FirebaseAuthTypes };
export { statusCodes };
// Auth exports
export const firebaseAuth = auth;
export const getAuthInstance = () => auth();
export const onAuthStateChanged = (
callback: (user: FirebaseAuthTypes.User | null) => void
) => {
return auth().onAuthStateChanged(callback);
};
// Firestore exports
export const firebaseFirestore = firestore;
export const getFirestoreInstance = () => firestore();
export const FieldValue = firestore.FieldValue;
export const Timestamp = firestore.Timestamp;
// Collection helpers
export const collection = (path: string) => firestore().collection(path);
export const doc = (collectionPath: string, docId: string) =>
firestore().collection(collectionPath).doc(docId);
// Messaging exports
export const firebaseMessaging = messaging;
export const getMessagingInstance = () => messaging();
export const AuthorizationStatus = messaging.AuthorizationStatus;
// Functions exports
export const firebaseFunctions = functions;
export const getFunctionsInstance = () => functions();
export const httpsCallable = (name: string) => functions().httpsCallable(name);
// Google Sign-In (Native)
export const signInWithGoogle = async (): Promise<{
user: FirebaseAuthTypes.User | null;
isNewUser: boolean;
error?: string;
}> => {
try {
// Check if device supports Google Play Services (Android only)
if (Platform.OS === "android") {
await GoogleSignin.hasPlayServices({
showPlayServicesUpdateDialog: true,
});
}
// Sign out first to always show account picker
try {
await GoogleSignin.signOut();
} catch (e) {
// Ignore sign out errors
}
// Sign in with Google
const signInResult = await GoogleSignin.signIn();
const idToken = signInResult.data?.idToken;
if (!idToken) {
return {
user: null,
isNewUser: false,
error: "No ID token received from Google",
};
}
// Create credential and sign in to Firebase
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
const userCredential = await auth().signInWithCredential(googleCredential);
const isNewUser = userCredential.additionalUserInfo?.isNewUser ?? false;
return { user: userCredential.user, isNewUser };
} catch (error: any) {
console.error("Google Sign-In error:", error);
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
return { user: null, isNewUser: false, error: "Sign in was cancelled" };
} else if (error.code === statusCodes.IN_PROGRESS) {
return {
user: null,
isNewUser: false,
error: "Sign in is already in progress",
};
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
return {
user: null,
isNewUser: false,
error: "Google Play Services not available",
};
}
// Handle iOS-specific errors
if (Platform.OS === "ios" && error.message?.includes("simulator")) {
return {
user: null,
isNewUser: false,
error:
"Google Sign-In may not work on iOS Simulator. Please test on a real device.",
};
}
return {
user: null,
isNewUser: false,
error: error.message || "Google Sign-In failed",
};
}
};
export const signOutFromGoogle = async (): Promise<void> => {
try {
await GoogleSignin.signOut();
} catch (error) {
console.error("Google Sign-Out error:", error);
}
};
// Phone Auth (Native)
export const signInWithPhoneNumber = async (phoneNumber: string) => {
return auth().signInWithPhoneNumber(phoneNumber);
};
// Email/Password Authentication (Native)
export const createUserWithEmailAndPassword = async (
email: string,
password: string
): Promise<{ user: FirebaseAuthTypes.User | null; error?: string }> => {
try {
const userCredential = await auth().createUserWithEmailAndPassword(
email,
password
);
return { user: userCredential.user };
} catch (error: any) {
console.error('Email/Password signup error:', error);
return {
user: null,
error: error.message || 'Failed to create account',
};
}
};
export const signInWithEmailAndPassword = async (
email: string,
password: string
): Promise<{ user: FirebaseAuthTypes.User | null; error?: string }> => {
try {
const userCredential = await auth().signInWithEmailAndPassword(
email,
password
);
return { user: userCredential.user };
} catch (error: any) {
console.error('Email/Password signin error:', error);
return {
user: null,
error: error.message || 'Failed to sign in',
};
}
};
// Firebase Auth sign out
export const signOut = async (): Promise<void> => {
await signOutFromGoogle();
await auth().signOut();
};
// Platform identifier
export const isNative = true;
export const isWeb = false;