/* * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose. * Your use of it is subject to your agreement with Google. */ package com.example.util; import com.example.repository.FirestoreBaseRepository; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.cloud.firestore.DocumentReference; import com.google.cloud.firestore.DocumentSnapshot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutionException; public class FirestoreDataImporter { private static final Logger logger = LoggerFactory.getLogger(FirestoreDataImporter.class); private static final String QUICK_REPLIES_COLLECTION_PATH_FORMAT = "artifacts/%s/quick-replies"; private final FirestoreBaseRepository firestoreBaseRepository; private final ObjectMapper objectMapper; private final boolean isImporterEnabled; public FirestoreDataImporter(FirestoreBaseRepository firestoreBaseRepository, ObjectMapper objectMapper) { this.firestoreBaseRepository = firestoreBaseRepository; this.objectMapper = objectMapper; this.isImporterEnabled = Boolean.parseBoolean(System.getProperty("firestore.data.importer.enabled")); } public void runImport() { if (isImporterEnabled) { try { importQuickReplies(); } catch (Exception e) { logger.error("Failed to import data to Firestore on startup", e); } } } private void importQuickReplies() throws IOException, ExecutionException, InterruptedException { String collectionPath = String.format(QUICK_REPLIES_COLLECTION_PATH_FORMAT, firestoreBaseRepository.getAppId()); importJson(collectionPath, "home"); importJson(collectionPath, "pagos"); importJson(collectionPath, "finanzas"); importJson(collectionPath, "lealtad"); importJson(collectionPath, "descubre"); importJson(collectionPath, "detalle-tdc"); importJson(collectionPath, "detalle-tdd"); importJson(collectionPath, "transferencia"); importJson(collectionPath, "retiro-sin-tarjeta"); importJson(collectionPath, "capsulas"); importJson(collectionPath, "inversiones"); importJson(collectionPath, "prestamos"); logger.info("All JSON files were imported successfully."); } private void importJson(String collectionPath, String documentId) throws IOException, ExecutionException, InterruptedException { String resourcePath = "/quick-replies/" + documentId + ".json"; try (InputStream inputStream = getClass().getResourceAsStream(resourcePath)) { if (inputStream == null) { logger.warn("Resource not found: {}", resourcePath); return; } Map localData = objectMapper.readValue(inputStream, new TypeReference>() {}); DocumentReference docRef = firestoreBaseRepository.getDocumentReference(collectionPath, documentId); if (firestoreBaseRepository.documentExists(docRef)) { DocumentSnapshot documentSnapshot = firestoreBaseRepository.getDocumentSnapshot(docRef); Map firestoreData = documentSnapshot.getData(); if (!Objects.equals(localData, firestoreData)) { firestoreBaseRepository.setDocument(docRef, localData); logger.info("Successfully updated {} in Firestore.", documentId); } } else { firestoreBaseRepository.setDocument(docRef, localData); logger.info("Successfully imported {} to Firestore.", documentId); } } } }