API プロバイダとして Vertex AI Gemini API を使用している場合にのみ使用できます。 |
Firebase AI Logic SDK を使用してアプリから Vertex AI Gemini API を呼び出すと、画像、PDF、動画、音声などのマルチモーダル入力に基づいてテキストを生成するように Gemini モデルにプロンプトを出すことができます。
入力のテキスト以外の部分(メディア ファイルなど)については、必要に応じて Cloud Storage for Firebase を使用してリクエストにファイルを含めることができます。この機能について知っておくべきことは次のとおりです。
Vertex AI Gemini API を使用している場合は、任意のマルチモーダル リクエスト(テキスト生成とチャットの両方など)で Cloud Storage for Firebase を使用できます。このガイドの例では、基本的なテキストと画像の入力を示しています。
ファイルの MIME タイプと Cloud Storage for Firebase URL(常に
gs://
で始まる)をリクエスト入力で指定します。これらの値は、Cloud Storage バケットにアップロードされたファイルに自動的に割り当てられるメタデータです。サポートされているファイル形式と URL を使用する必要があります。
このソリューション ガイドでは、Cloud Storage for Firebase を設定し、アプリから Cloud Storage for Firebase バケットにファイルをアップロードし、Gemini API へのマルチモーダル リクエストにファイルの MIME タイプと Cloud Storage for Firebase URL を含める方法について説明します。
コードサンプルを確認したい場合は、または、Cloud Storage for Firebase をすでに設定していて、マルチモーダル リクエストで使用できる状態ですか?
アプリで Cloud Storage for Firebase を使用する理由
Cloud Storage for Firebase は、Google Cloud Storage と同じ高速で安全かつスケーラブルなインフラストラクチャを使用して BLOB とファイルを保存します。そのクライアント SDK は、モバイルアプリとウェブアプリ用に特別に構築されています。
Firebase AI Logic SDK の場合、リクエストの最大サイズは 20 MB です。リクエストが大きすぎると、HTTP 413 エラーが発生します。ファイルのサイズが原因でリクエストの合計サイズが 20 MB を超える場合は、Cloud Storage for Firebase URL を使用してマルチモーダル リクエストにファイルを含めます。ただし、ファイルが小さい場合は、多くの場合、そのファイルをインライン データとして直接渡すことができます(ただし、インライン データとして提供されたファイルは転送中に Base64 にエンコードされるため、リクエストのサイズが大きくなります)。
Cloud Storage for Firebase を使用するメリットは次のとおりです。
エンドユーザーがアプリから Cloud Storage for Firebase バケットに画像を直接アップロードできるようにし、ファイルの MIME タイプと Cloud Storage for Firebase URL(ファイルの識別子)を指定するだけで、それらの画像をマルチモーダル プロンプトに含めることができます。
エンドユーザーが画像を提供する必要が生じた場合、特にネットワークの品質が低い場合や不安定な場合は、エンドユーザーの時間を節約し、帯域幅を削減できます。
- ファイルのアップロードまたはダウンロードが中断された場合、Cloud Storage for Firebase SDK は中断したところからオペレーションを自動的に再開します。
- アップロードした同じファイルを複数回使用できます。エンドユーザーは、アプリで必要になるたびに(新しいマルチモーダル リクエストの場合など)同じファイルをアップロードする必要はありません。
Cloud Storage for Firebase に保存されているファイルへのエンドユーザーのアクセスを制限するには、Firebase Security Rules を使用します。これにより、承認済みユーザーのみがファイルをアップロード、ダウンロード、削除できるようになります。
バケット内のファイルには、Firebase または Google Cloud からアクセスできます。これにより、Google Cloud Storage API を使用して、画像のフィルタリングや動画のコード変換などのサーバーサイド処理を柔軟に行うことができます。
サポートされているファイルと URL の種類
Firebase AI Logic SDK で Cloud Storage for Firebase URL を使用する場合のファイルと URL の要件は次のとおりです。
ファイルは、マルチモーダル リクエストの入力ファイルの要件を満たしている必要があります。これには、MIME タイプやファイルサイズなどの要件が含まれます。
ファイルは Cloud Storage for Firebase バケットに保存する必要があります(つまり、Firebase サービス(Firebase Security Rules など)がバケットにアクセスできる必要があります)。Firebase コンソールでバケットを表示できる場合は、Cloud Storage for Firebase バケットです。
Cloud Storage for Firebase バケットは、アプリを登録した Firebase プロジェクトと同じプロジェクトに存在する必要があります。
ファイルの Cloud Storage for Firebase URL は
gs://
で始まる必要があります。これは、すべての Google Cloud Storage URL が作成される方法です。ファイルの URL は「ブラウザ」の URL(インターネットで見つかった画像の URL など)にすることはできません。
また、バケットの Firebase Security Rules で、ファイルへの適切なアクセスを許可する必要があります。例:
公開ルールがある場合、すべてのユーザーまたはクライアントがファイルにアクセスできます。
堅牢なルール (強く推奨)がある場合、Firebase は、ログインしたユーザーまたはクライアントがファイルに十分なアクセス権を持っていることを確認してから、指定された URL で呼び出しを許可します。
Firebase AI Logic で Cloud Storage for Firebase URL を使用する
API プロバイダとして Vertex AI Gemini API を使用している場合にのみ使用できます。 |
ステップ 1: Cloud Storage for Firebase を設定する
Cloud Storage for Firebase の設定手順については、スタートガイド(iOS+ | Android | ウェブ | Flutter | Unity)をご覧ください。
必要な大まかなタスクは次のとおりです。
Firebase プロジェクトに Cloud Storage for Firebase バケットを作成またはインポートします。
このバケットに Firebase Security Rules を適用します。Rules は、承認されたエンドユーザーへのアクセスを制限することで、ファイルを保護するのに役立ちます。
Cloud Storage for Firebase のクライアント ライブラリをアプリに追加します。
このタスクはスキップできますが、その場合は常に リクエストに MIME タイプと URL 値を明示的に含める必要があります。
ステップ 2: バケットにファイルをアップロードする
Cloud Storage のドキュメントでは、バケットにファイルをアップロードするさまざまな方法について説明しています。たとえば、エンドユーザーのデバイスからローカル ファイル(カメラの写真や動画など)をアップロードできます。詳細: iOS+ | Android | ウェブ | Flutter | Unity
ファイルをバケットにアップロードすると、Cloud Storage は次の 2 つの情報を自動的にファイルに適用します。これらの値はリクエストに含める必要があります(このガイドの次のステップを参照)。
MIME タイプ: ファイルのメディア タイプ(
image/png
など)。アップロード時に MIME タイプが自動的に検出され、そのメタデータがバケット内のオブジェクトに適用されます。ただし、必要に応じてアップロード時に MIME タイプを指定できます。Cloud Storage for Firebase URL: ファイルの一意の識別子。先頭は
gs://
でなければなりません。
ステップ 3: マルチモーダル リクエストにファイルの MIME タイプと URL を含める
ファイルをバケットに保存したら、その MIME タイプと URL をリクエストに含めることができます。これらの例ではストリーミング以外の generateContent
リクエストを示していますが、ストリーミングやチャットで URL を使用することもできます。
リクエストにファイルを含めるには、次のいずれかのオプションを使用します。
オプション 1: ストレージ リファレンスを使用して MIME タイプと URL を含める
オプション 2: MIME タイプと URL を明示的に含める
オプション 1: Storage 参照を使用して MIME タイプと URL を含める
この例を試す前に、Firebase AI Logic SDK のスタートガイドを完了していることを確認してください。 |
ファイルをバケットにアップロードした直後に、(Storage 参照を介して)ファイルをリクエストにすぐに含める場合は、このオプションを使用します。この呼び出しには、MIME タイプと Cloud Storage for Firebase URL の両方が必要です。
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
Kotlin の場合、この SDK のメソッドは suspend 関数であり、Coroutine スコープから呼び出す必要があります。// 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
Java の場合、この SDK のメソッドは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.");
オプション 2: MIME タイプと URL を明示的に含める
この例を試す前に、Firebase AI Logic SDK のスタートガイドを完了していることを確認してください。 |
MIME タイプと Cloud Storage for Firebase URL の値がわかっていて、それらをマルチモーダル リクエストに明示的に含める場合は、このオプションを使用します。この呼び出しには、MIME タイプと 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
Kotlin の場合、この SDK のメソッドは suspend 関数であり、Coroutine スコープから呼び出す必要があります。// 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
Java の場合、この SDK のメソッドは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.");