const admin = require("firebase-admin"); const { BATCH_TYPE } = require("../config/types"); async function deleteFolder(path) { try { console.log(`Deleting folder: ${path}`); const bucket = admin.storage().bucket(); await bucket.deleteFiles({ prefix: path, force: true }); console.log(`Folder ${path} deleted successfully`); } catch (e) { console.log(e); } } async function batchFirestore({ path = "", // ADD only docs = [], // not for ADD data = {}, // not for DELETE type = BATCH_TYPE.UPDATE, }) { try { if (docs?.length === 0 && type !== BATCH_TYPE.ADD) { console.log(`Aucun document trouvé dans la collection ${path}.`); return; } // Préparer des lots pour les opérations const batches = []; let currentBatch = admin.firestore().batch(); let operationCounter = 0; docs.forEach((doc) => { const ref = doc?.ref || (typeof doc?.path === "string" ? admin.firestore().doc(doc.path) : null); const payload = doc && typeof doc.data === "object" && doc.data !== null && !Array.isArray(doc.data) ? doc.data : data; if (type === BATCH_TYPE.ADD) { // Pour ADD, créer un nouveau document avec ID automatique const newDocRef = admin.firestore().collection(path).doc(); currentBatch.set(newDocRef, data); } else if (type === BATCH_TYPE.UPDATE) { if (!ref) { throw new Error("batchFirestore UPDATE nécessite une référence de document."); } if (!payload || Object.keys(payload).length === 0) { throw new Error("batchFirestore UPDATE nécessite des données à écrire."); } currentBatch.set(ref, payload, { merge: true }); } else if (type === BATCH_TYPE.DELETE) { if (!ref) { throw new Error("batchFirestore DELETE nécessite une référence de document."); } currentBatch.delete(ref); } else { throw new Error(`Opération non supportée : ${type}`); } operationCounter++; // Si le lot atteint la limite de 500 opérations, le sauvegarder et en créer un nouveau if (operationCounter === 500) { batches.push(currentBatch); currentBatch = admin.firestore().batch(); operationCounter = 0; } }); // Ajouter le dernier lot si des opérations y sont présentes if (operationCounter > 0) { batches.push(currentBatch); } // Exécuter tous les lots en parallèle await Promise.all(batches.map((batch) => batch.commit())); } catch (error) { console.error( `Erreur lors des opérations ${type} pour la collection ${path} :`, error, ); } } exports.batchFirestore = batchFirestore; exports.deleteFolder = deleteFolder;