/* eslint-disable @typescript-eslint/camelcase */ import FirebaseAdmin from 'firebase-admin'; import axios from 'axios'; import { newError } from '@seed/helpers/Error'; export interface FirebaseUser { aud: string; auth_time: number; email: string | undefined; email_verified: boolean | undefined; exp: number; firebase: { identities: any; sign_in_provider: 'custom' | 'password' | 'phone' | 'anonymous' | 'google.com' | 'facebook.com' | 'github.com' | 'twitter.com'; }; iat: number; name: string; picture: string | undefined; uid: string; } export default class Firebase { private static instance: Firebase; private constructor() { try { const base = { type: 'service_account', project_id: process.env.FIREBASE_project_id || '', private_key_id: process.env.FIREBASE_private_key_id || '', private_key: process.env.FIREBASE_private_key ? process.env.FIREBASE_private_key.replace(/\\n/g, '\n') : '', client_email: process.env.FIREBASE_client_email || '', client_id: process.env.FIREBASE_client_id || '', auth_uri: process.env.FIREBASE_auth_uri || '', token_uri: process.env.FIREBASE_token_uri || '', auth_provider_x509_cert_url: process.env.FIREBASE_auth_provider_x509_cert_url || '', client_x509_cert_url: process.env.FIREBASE_client_x509_cert_url || '', apiKey: process.env.FIREBASE_apiKey || '', }; FirebaseAdmin.initializeApp({ credential: FirebaseAdmin.credential.cert({ projectId: base.project_id, clientEmail: base.client_email, privateKey: base.private_key, }), }); } catch (error) { if (!/already exists/.test(error.message)) { console.error('Firebase initialization error raised', error.stack); } } } public static getInstance(): Firebase { if (!Firebase.instance) { Firebase.instance = new Firebase(); } return Firebase.instance; } /* * IDENTIFY TOKEN */ public async tokenIdentify(token: string): Promise { try { const res = await FirebaseAdmin.auth().verifyIdToken(token); return res; } catch (err) { throw await newError(2011, err); } } /* * ADMIN FUNCTIONS */ public async createUser(obj: { email: string; password: string }): Promise { try { return await FirebaseAdmin.auth().createUser({ ...obj, emailVerified: true, }); } catch (err) { throw newError(2012, err); } } public async getUserByEmail(email: string): Promise { try { return await FirebaseAdmin.auth().getUserByEmail(email); } catch (err) { throw newError(2013, err); } } public async updatePassword(obj: { uid: string; password: string }): Promise { try { return await FirebaseAdmin.auth().updateUser(obj.uid, { password: obj.password, emailVerified: true, }); } catch (err) { throw newError(2013, err); } } public async updateEmail(obj: { uid: string; email: string }): Promise { try { return await FirebaseAdmin.auth().updateUser(obj.uid, { email: obj.email, emailVerified: true, }); } catch (err) { throw newError(2013, err); } } public async deleteUser(obj: { uid: string }): Promise { try { return await FirebaseAdmin.auth().deleteUser(obj.uid); } catch (err) { throw newError(2013, err); } } public async getResetPasswordLink(email: string): Promise { try { return await FirebaseAdmin.auth().generatePasswordResetLink(email); } catch (err) { throw newError(2013, err); } } public async getEmailConfirmationLink(email: string): Promise { try { return await FirebaseAdmin.auth().generateEmailVerificationLink(email); } catch (err) { throw newError(2013, err); } } public async createTokenId(email: string): Promise { try { const firebaseUser = await FirebaseAdmin.auth().getUserByEmail(email); const customToken = await FirebaseAdmin.auth().createCustomToken(firebaseUser.uid); const r = await axios.post( `https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=${process.env.FIREBASE_apiKey}`, { token: customToken, returnSecureToken: true, }, ); // console.log(r.data); return r.data; } catch (err) { throw err; } } public async getMagicLink(email): Promise { try { const actionCodeSettings: any = { // URL you want to redirect back to. The domain (www.example.com) for // this URL must be whitelisted in the Firebase Console. // This must be true for email link sign-in. url: process.env.MAGIC_LINK_URL ? process.env.MAGIC_LINK_URL : 'https://makeit-studio.com/magicLink', handleCodeInApp: true, // FDL custom domain. // dynamicLinkDomain: 'coolapp.page.link' }; if (process.env.IOS_PACKAGE_NAME && process.env.IOS_PACKAGE_NAME != '') actionCodeSettings.iOS = { bundleId: process.env.IOS_PACKAGE_NAME, }; if (process.env.ANDROID_PACKAGE_NAME && process.env.ANDROID_PACKAGE_NAME != '') actionCodeSettings.android = { packageName: process.env.ANDROID_PACKAGE_NAME, installApp: true, }; return await FirebaseAdmin.auth().generateSignInWithEmailLink(email, actionCodeSettings); } catch (err) { throw err; } } /* * PUSH NOTIFICATION FUNCTIONS */ public async sendPushNotification(registrationToken: string | string[], title: string, body: string, data = {}): Promise { try { const firebaseInfo = await FirebaseAdmin.messaging().sendToDevice(registrationToken, { data, notification: { title: title, body: body, }, }); console.log('firebase success', firebaseInfo); } catch (error) { console.log('firebase error', error); } return true; } }