Incluye archivos grandes en solicitudes multimodales y administra archivos con Cloud Storage para Firebase

Solo está disponible cuando usas Vertex AI Gemini API como tu proveedor de la API.

Cuando llamas a Vertex AI Gemini API desde tu app con un SDK de Firebase AI Logic, puedes solicitarle a un modelo de Gemini que genere texto basado en una entrada multimodal, como imágenes, PDFs, videos y audio.

Para las partes no textuales de la entrada (como los archivos multimedia), puedes usar Cloud Storage for Firebase de forma opcional para incluir archivos en la solicitud. A continuación, te mostramos un resumen de lo que debes saber sobre esta función:

  • Puedes usar Cloud Storage for Firebase con cualquier solicitud multimodal (como la generación de texto y el chat) si usas Vertex AI Gemini API. Los ejemplos de esta guía muestran una entrada básica de texto e imagen.

  • En la entrada de la solicitud, especificas el tipo de MIME del archivo y su URL de Cloud Storage for Firebase (que siempre comienza con gs://). Estos valores son metadatos que se asignan automáticamente a cualquier archivo que se sube a un bucket de Cloud Storage.

  • Debes usar un tipo de archivo y una URL compatibles.


En esta guía de soluciones, se describe cómo configurar Cloud Storage for Firebase, subir un archivo a un bucket de Cloud Storage for Firebase desde tu app y, luego, incluir el tipo de MIME y la URL de Cloud Storage for Firebase del archivo en tu solicitud multimodal a Gemini API.

¿Quieres ver los ejemplos de código? ¿O ya configuraste Cloud Storage for Firebase y puedes comenzar a usarlo con tus solicitudes multimodales?

Ir a los ejemplos de código

¿Por qué usar Cloud Storage for Firebase con tu app?

Cloud Storage for Firebase usa la misma infraestructura rápida, segura y escalable que Google Cloud Storage para almacenar BLOBs y archivos, y sus SDKs de cliente están diseñados específicamente para apps web y para dispositivos móviles.

Para los SDKs de Firebase AI Logic, el tamaño máximo de la solicitud es de 20 MB. Recibirás un error HTTP 413 si una solicitud es demasiado grande. Si el tamaño de un archivo hará que el tamaño total de la solicitud supere los 20 MB, usa una URL de Cloud Storage for Firebase para incluir el archivo en tu solicitud multimodal. Sin embargo, si un archivo es pequeño, a menudo puedes pasarlo directamente como datos intercalados (ten en cuenta que un archivo proporcionado como datos intercalados se codifica en Base64 durante la transmisión, lo que aumenta el tamaño de la solicitud).

Estos son algunos beneficios adicionales de usar Cloud Storage for Firebase:

  • Puedes hacer que los usuarios finales suban imágenes directamente desde tu app a un bucket de Cloud Storage for Firebase y, luego, incluir esas imágenes en tus instrucciones multimodales con solo especificar el tipo de MIME y la URL de Cloud Storage for Firebase del archivo (que es un identificador del archivo).

  • Puedes ahorrarles tiempo y ancho de banda a tus usuarios finales si necesitan proporcionar imágenes, en especial si tienen una calidad de red deficiente o inestable.

    • Si se interrumpe la carga o descarga de un archivo, los SDKs de Cloud Storage for Firebase reinician automáticamente la operación desde el punto en que se detuvo.
    • El mismo archivo subido se puede usar varias veces sin que el usuario final tenga que subirlo cada vez que se necesite en tu app (como en una nueva solicitud multimodal).
  • Puedes restringir el acceso de los usuarios finales a los archivos almacenados en Cloud Storage for Firebase con Firebase Security Rules, que solo permite que un usuario autorizado suba, descargue o borre archivos.

  • Puedes acceder a los archivos de tu bucket desde Firebase o desde Google Cloud, lo que te brinda la flexibilidad de realizar procesamiento en el servidor, como el filtrado de imágenes o la transcodificación de videos con las APIs de Google Cloud Storage.

¿Qué tipos de archivos y URLs se admiten?

Estos son los requisitos para los archivos y las URLs cuando deseas usar URLs de Cloud Storage for Firebase con los SDKs de Firebase AI Logic:

  • El archivo debe cumplir con los requisitos de los archivos de entrada para las solicitudes multimodales. Esto incluye requisitos como el tipo de MIME y el tamaño del archivo.

  • El archivo debe almacenarse en un bucket de Cloud Storage for Firebase (lo que significa que los servicios de Firebase, como Firebase Security Rules, pueden acceder al bucket). Si puedes ver tu bucket en la consola de Firebase, significa que es un bucket de Cloud Storage for Firebase.

  • El bucket de Cloud Storage for Firebase debe estar en el mismo proyecto de Firebase en el que registraste tu app.

  • La URL Cloud Storage for Firebase del archivo debe comenzar con gs://, que es la forma en que se construyen todas las URLs de Google Cloud Storage.

  • La URL del archivo no puede ser una URL de "navegador" (por ejemplo, la URL de una imagen que encuentras en Internet).

Además, el Firebase Security Rules de tu bucket debe permitir el acceso adecuado al archivo. Por ejemplo:

  • Si tienes reglas públicas, cualquier usuario o cliente puede acceder al archivo.

  • Si tienes reglas sólidas (muy recomendadas), Firebase verificará que el usuario o cliente que accedió tenga suficiente acceso al archivo antes de permitir que la llamada se realice con la URL proporcionada.

Usa URLs de Cloud Storage for Firebase con Firebase AI Logic

Solo está disponible cuando usas Vertex AI Gemini API como tu proveedor de la API.

Paso 1: Configura Cloud Storage for Firebase

Puedes encontrar instrucciones detalladas para configurar Cloud Storage for Firebase en su guía de introducción: iOS+ | Android | Web | Flutter | Unity

Estas son las tareas de alto nivel que deberás realizar:

  1. Crea o importa un bucket de Cloud Storage for Firebase en tu proyecto de Firebase.

  2. Aplica Firebase Security Rules a este bucket. Rules te ayudan a proteger tus archivos restringiendo el acceso a los usuarios finales autorizados.

  3. Agrega la biblioteca cliente para Cloud Storage for Firebase a tu app.

    Ten en cuenta que puedes omitir esta tarea, pero, en ese caso, siempre deberás incluir de forma explícita los valores de tipo MIME y URL en tus solicitudes.

Paso 2: Sube un archivo a un bucket

En la documentación de Cloud Storage, puedes obtener información sobre las diferentes formas de subir archivos a un bucket. Por ejemplo, puedes subir archivos locales desde el dispositivo del usuario final, como fotos y videos de la cámara. Obtén más información: iOS+ | Android | Web | Flutter | Unity

Cuando subes un archivo a un bucket, Cloud Storage aplica automáticamente la siguiente información al archivo. Deberás incluir estos valores en la solicitud (como se muestra en el siguiente paso de esta guía).

  • Tipo de MIME: Es el tipo de medio del archivo (por ejemplo, image/png). Intentaremos detectar automáticamente el tipo de MIME durante la carga y aplicaremos esos metadatos al objeto en el bucket. Sin embargo, puedes especificar el tipo de MIME durante la carga de forma opcional.

  • URL de Cloud Storage for Firebase: Es un identificador único del archivo. La URL debe comenzar con gs://.

Paso 3: Incluye el tipo de MIME y la URL del archivo en una solicitud multimodal

Una vez que tengas un archivo almacenado en un bucket, puedes incluir su tipo de MIME y URL en una solicitud. Ten en cuenta que estos ejemplos muestran una solicitud generateContent sin transmisión, pero también puedes usar URLs con transmisión y chat.

Para incluir el archivo en la solicitud, puedes usar cualquiera de las siguientes opciones:

Opción 1: Incluye el tipo de MIME y la URL con una referencia de Storage

Antes de probar este ejemplo, asegúrate de haber completado la guía de introducción de los SDKs de Firebase AI Logic.

Usa esta opción si acabas de subir el archivo al bucket y quieres incluirlo de inmediato (a través de una referencia de Storage) en la solicitud. La llamada requiere el tipo de MIME y la URL de Cloud Storage for Firebase.

Swift

// Upload an image file using Cloud Storage for Firebase.
let storageRef = Storage.storage().reference(withPath: "images/image.jpg")
guard let imageURL = Bundle.main.url(forResource: "image", withExtension: "jpg") else {
  fatalError("File 'image.jpg' not found in main bundle.")
}
let metadata = try await storageRef.putFileAsync(from: imageURL)

// Get the MIME type and Cloud Storage for Firebase URL.
guard let mimeType = metadata.contentType else {
  fatalError("The MIME type of the uploaded image is nil.")
}
// Construct a URL in the required format.
let storageURL = "gs://\(storageRef.bucket)/\(storageRef.fullPath)"

let prompt = "What's in this picture?"
// Construct the imagePart with the MIME type and the URL.
let imagePart = FileDataPart(uri: storageURL, mimeType: mimeType)

// To generate text output, call generateContent with the prompt and the imagePart.
let result = try await model.generateContent(prompt, imagePart)
if let text = result.text {
  print(text)
}

Kotlin

En Kotlin, los métodos de este SDK son funciones de suspensión y deben llamarse desde un alcance de corrutina.
// Upload an image file using Cloud Storage for Firebase.
val storageRef = Firebase.storage.reference.child("images/image.jpg")
val fileUri = Uri.fromFile(File("image.jpg"))
try {
    val taskSnapshot = storageRef.putFile(fileUri).await()
    // Get the MIME type and Cloud Storage for Firebase file path.
    val mimeType = taskSnapshot.metadata?.contentType
    val bucket = taskSnapshot.metadata?.bucket
    val filePath = taskSnapshot.metadata?.path

    if (mimeType != null && bucket != null) {
        // Construct a URL in the required format.
        val storageUrl = "gs://$bucket/$filePath"
        // Construct a prompt that includes text, the MIME type, and the URL.
        val prompt = content {
            fileData(mimeType = mimeType, uri = storageUrl)
            text("What's in this picture?")
        }
        // To generate text output, call generateContent with the prompt.
        val response = generativeModel.generateContent(prompt)
        println(response.text)
    }
} catch (e: StorageException) {
    // An error occurred while uploading the file.
} catch (e: GoogleGenerativeAIException) {
    // An error occurred while generating text.
}

Java

En Java, los métodos de este SDK devuelven un ListenableFuture.
// Upload an image file using Cloud Storage for Firebase.
StorageReference storage = FirebaseStorage.getInstance().getReference("images/image.jpg");
Uri fileUri = Uri.fromFile(new File("images/image.jpg"));

storage.putFile(fileUri).addOnSuccessListener(taskSnapshot -> {
    // Get the MIME type and Cloud Storage for Firebase file path.
    String mimeType = taskSnapshot.getMetadata().getContentType();
    String bucket = taskSnapshot.getMetadata().getBucket();
    String filePath = taskSnapshot.getMetadata().getPath();

    if (mimeType != null && bucket != null) {
        // Construct a URL in the required format.
        String storageUrl = "gs://" + bucket + "/" + filePath;
        // Create a prompt that includes text, the MIME type, and the URL.
        Content prompt = new Content.Builder()
                .addFileData(storageUrl, mimeType)
                .addText("What's in this picture?")
                .build();

        // To generate text output, call generateContent with the prompt.
        GenerativeModelFutures modelFutures = GenerativeModelFutures.from(model);
        ListenableFuture<GenerateContentResponse> response = modelFutures.generateContent(prompt);
        Futures.addCallback(response, new FutureCallback<>() {
            @Override
            public void onSuccess(GenerateContentResponse result) {
                String resultText = result.getText();
                System.out.println(resultText);
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                t.printStackTrace();
            }
        }, executor);
    }
}).addOnFailureListener(e -> {
    // An error occurred while uploading the file.
    e.printStackTrace();
});

Web

// Upload an image file using Cloud Storage for Firebase.
const storageRef = ref(storage, "image.jpg");
const uploadResult = await uploadBytes(storageRef, file);

// Get the MIME type and Cloud Storage for Firebase URL.
// toString() is the simplest way to construct the Cloud Storage for Firebase URL
// in the required format.
const mimeType = uploadResult.metadata.contentType;
const storageUrl = uploadResult.ref.toString();

// Construct the imagePart with the MIME type and the URL.
const imagePart = { fileData: { mimeType, fileUri: storageUrl }};

// To generate text output, call generateContent with the prompt and imagePart.
const result = await model.generateContent([prompt, imagePart]);
console.log(result.response.text());

Dart

// Upload an image file using Cloud Storage for Firebase.
final storageRef = FirebaseStorage.instance.ref();
final imageRef = storageRef.child("images/image.jpg");
await imageRef.putData(data);

// Get the MIME type and Cloud Storage for Firebase file path.
final metadata = await imageRef.getMetadata();
final mimeType = metadata.contentType;
final bucket = imageRef.bucket;
final fullPath = imageRef.fullPath;

final prompt = TextPart("What's in the picture?");
// Construct a URL in the required format.
final storageUrl = 'gs://$bucket/$fullPath';
// Construct the filePart with the MIME type and the URL.
final filePart = FileData(mimeType, storageUrl);
// To generate text output, call generateContent with the text and the filePart.
final response = await model.generateContent([
  Content.multi([prompt, filePart])
]);
print(response.text);

Unity

var storageRef = FirebaseStorage.DefaultInstance.GetReference("images/image.jpg");
var metadata = await storageRef.PutFileAsync(filePathToJpg);

// Get the MIME type and Cloud Storage for Firebase URL.
var mimeType = metadata.ContentType;
// Construct a URL in the required format.
var storageURL = new Uri($"gs://{storageRef.Bucket}/{storageRef.Path}");

var prompt = ModelContent.Text("What's in this picture?");
// Construct a FileData that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
var fileData = ModelContent.FileData(mimeType, storageURL);

// To generate text output, call GenerateContentAsync with the prompt and fileData.
var response = await model.GenerateContentAsync(new [] { prompt, fileData });
UnityEngine.Debug.Log(response.Text ?? "No text in response.");

Opción 2: Incluye el tipo de MIME y la URL de forma explícita

Antes de probar este ejemplo, asegúrate de haber completado la guía de introducción de los SDKs de Firebase AI Logic.

Usa esta opción si conoces los valores del tipo de MIME y la URL de Cloud Storage for Firebase, y deseas incluirlos de forma explícita en la solicitud multimodal. La llamada requiere el tipo de MIME y la URL.

Swift

let prompt = "What's in this picture?"
// Construct an imagePart that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
let imagePart = FileDataPart(uri: "gs://bucket-name/path/image.jpg", mimeType: "image/jpeg")

// To generate text output, call generateContent with the prompt and imagePart.
let result = try await model.generateContent(prompt, imagePart)
if let text = result.text {
  print(text)
}

Kotlin

En Kotlin, los métodos de este SDK son funciones de suspensión y deben llamarse desde un alcance de corrutina.
// Construct a prompt that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
val prompt = content {
    fileData(mimeType = "image/jpeg", uri = "gs://bucket-name/path/image.jpg")
    text("What's in this picture?")
}
// To generate text output, call generateContent with the prompt.
val response = generativeModel.generateContent(prompt)
println(response.text)

Java

En Java, los métodos de este SDK devuelven un ListenableFuture.
// Construct a prompt that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
Content prompt = new Content.Builder()
        .addFilePart("gs://bucket-name/path/image.jpg", "image/jpeg")
        .addText("What's in this picture?")
        .build();

// To generate text output, call generateContent with the prompt
GenerativeModelFutures modelFutures = GenerativeModelFutures.from(model);
ListenableFuture<GenerateContentResponse> response = modelFutures.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        String resultText = result.getText();
        System.out.println(resultText);
    }

    @Override
    public void onFailure(@NonNull Throwable t) {
        t.printStackTrace();
    }
}, executor);

Web

const prompt = "What's in this picture?";
// Construct an imagePart that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
const imagePart = { fileData: { mimeType: "image/jpeg", fileUri: "gs://bucket-name/path/image.jpg" }};

// To generate text output, call generateContent with the prompt and imagePart.
const result = await model.generateContent([prompt, imagePart]);
console.log(result.response.text());

Dart

final prompt = TextPart("What's in the picture?");
// Construct a filePart that explicitly includes the MIME type and Cloud Storage for Firebase URL values.
final filePart = FileData('image/jpeg', 'gs://bucket-name/path/image.jpg'),
// To generate text output, call generateContent with the prompt and filePart.
final response = await model.generateContent([
  Content.multi([prompt, filePart])
]);
print(response.text);

Unity

var prompt = ModelContent.Text("What's in this picture?");
// Construct a FileData that explicitly includes the MIME type and
// Cloud Storage for Firebase URL values.
var fileData = ModelContent.FileData(
  mimeType: "image/jpeg",
  uri: new Uri("gs://bucket-name/path/image.jpg")
);

// To generate text output, call GenerateContentAsync with the prompt and fileData.
var response = await model.GenerateContentAsync(new [] { prompt, fileData });
UnityEngine.Debug.Log(response.Text ?? "No text in response.");