11import { badRequest } from "../../common/error" ;
2- import { initializeApp , deleteApp , cert } from "firebase-admin/app" ;
2+ import { getApps , initializeApp , deleteApp , cert , App } from "firebase-admin/app" ;
33import { getDatabase , Reference } from "firebase-admin/database" ;
44import {
55 CollectionReference ,
@@ -64,6 +64,23 @@ function extractCursorValues(values: any[]): any[] {
6464 ) . filter ( value => value !== undefined ) ;
6565}
6666
67+ const appCache : { [ firestoreId : string ] : any } = { } ; // A cache for storing initialized apps by firestoreId
68+
69+ function getOrInitializeApp ( serviceAccount : any , databaseUrl : string , firestoreId : string ) : App {
70+ const existingApp = getApps ( ) . find ( ( app ) => app . name === firestoreId ) ;
71+
72+ if ( existingApp ) {
73+ return existingApp ; // Return the existing app
74+ }
75+
76+ // Initialize a new app with the given name
77+ return initializeApp ( {
78+ credential : cert ( serviceAccount ) ,
79+ databaseURL : databaseUrl ,
80+ projectId : firestoreId ,
81+ } , firestoreId ) ;
82+ }
83+
6784export async function runFirebasePlugin (
6885 actionData : ActionDataType ,
6986 dataSourceConfig : DataSourceDataType
@@ -72,33 +89,29 @@ export async function runFirebasePlugin(
7289 const { privateKey, databaseUrl, firestoreId } = dataSourceConfig ;
7390 const serviceAccount = JSON . parse ( privateKey ) ;
7491
75- const app = initializeApp ( {
76- credential : cert ( serviceAccount ) ,
77- databaseURL : databaseUrl ,
78- projectId : firestoreId ,
79- } ) ;
92+ const app = getOrInitializeApp ( serviceAccount , databaseUrl , firestoreId ) ;
8093
8194 const witDbRef = < T > ( fn : ( ref : Reference ) => T ) : T => {
8295 if ( ! ( "databaseRef" in actionData ) ) {
8396 throw badRequest ( "not a realtime database action:" + actionName ) ;
8497 }
85- const ref = getDatabase ( ) . ref ( actionData . databaseRef ) ;
98+ const ref = getDatabase ( app ) . ref ( actionData . databaseRef ) ;
8699 return fn ( ref ) ;
87100 } ;
88101
89102 const withFirestoreCollection = < T > ( fn : ( ref : CollectionReference ) => T ) : T => {
90103 if ( ! ( "collection" in actionData ) ) {
91104 throw badRequest ( "not a firestore action with collection:" + actionName ) ;
92105 }
93- const ref = getFirestore ( ) . collection ( actionData . collection ) ;
106+ const ref = getFirestore ( app ) . collection ( actionData . collection ) ;
94107 return fn ( ref ) ;
95108 } ;
96109
97110 const withFirestoreDoc = < T > ( fn : ( ref : DocumentReference ) => T ) : T => {
98111 if ( ! ( "collection" in actionData ) || ! ( "documentId" in actionData ) ) {
99112 throw badRequest ( "not a firestore action with collection and documentId:" + actionName ) ;
100113 }
101- const ref = getFirestore ( ) . collection ( actionData . collection ) . doc ( actionData . documentId ) ;
114+ const ref = getFirestore ( app ) . collection ( actionData . collection ) . doc ( actionData . documentId ) ;
102115 return fn ( ref ) ;
103116 } ;
104117
@@ -130,9 +143,9 @@ export async function runFirebasePlugin(
130143 if ( actionName === "FS.GetCollections" ) {
131144 let collections ;
132145 if ( actionData . parentDocumentId ) {
133- collections = await getFirestore ( ) . doc ( actionData . parentDocumentId ) . listCollections ( ) ;
146+ collections = await getFirestore ( app ) . doc ( actionData . parentDocumentId ) . listCollections ( ) ;
134147 } else {
135- collections = await getFirestore ( ) . listCollections ( ) ;
148+ collections = await getFirestore ( app ) . listCollections ( ) ;
136149 }
137150 return collections . map ( ( i ) => i . id ) ;
138151 }
@@ -317,7 +330,8 @@ export async function runFirebasePlugin(
317330 return successResult ;
318331 } ) ;
319332 }
320- } finally {
321- deleteApp ( app ) ;
333+ } catch ( error ) {
334+ console . error ( `Error in action ${ actionData . actionName } :` , error ) ;
335+ throw error ;
322336 }
323337}
0 commit comments