Mit Cloud Storage for Firebase können Sie schnell und einfach Dateien in einen von Firebase bereitgestellten und verwalteten Cloud Storage-Bucket hochladen.
Dateien hochladen
Wenn Sie eine Datei in Cloud Storage hochladen möchten, erstellen Sie zuerst eine Referenz auf den vollständigen Pfad der Datei, einschließlich des Dateinamens.
Kotlin
// Create a storage reference from our app val storageRef = storage.reference // Create a reference to "mountains.jpg" val mountainsRef = storageRef.child("mountains.jpg") // Create a reference to 'images/mountains.jpg' val mountainImagesRef = storageRef.child("images/mountains.jpg") // While the file names are the same, the references point to different files mountainsRef.name == mountainImagesRef.name // true mountainsRef.path == mountainImagesRef.path // false
Java
// Create a storage reference from our app StorageReference storageRef = storage.getReference(); // Create a reference to "mountains.jpg" StorageReference mountainsRef = storageRef.child("mountains.jpg"); // Create a reference to 'images/mountains.jpg' StorageReference mountainImagesRef = storageRef.child("images/mountains.jpg"); // While the file names are the same, the references point to different files mountainsRef.getName().equals(mountainImagesRef.getName()); // true mountainsRef.getPath().equals(mountainImagesRef.getPath()); // false
Nachdem Sie eine entsprechende Referenz erstellt haben, rufen Sie die Methode putBytes(), putFile() oder putStream() auf, um die Datei in Cloud Storage hochzuladen.
Sie können keine Daten mit einem Verweis auf das Stammverzeichnis Ihres Cloud Storage-Buckets hochladen. Der Verweis muss auf eine untergeordnete URL verweisen.
Aus Daten im Arbeitsspeicher hochladen
Die Methode putBytes() ist die einfachste Möglichkeit, eine Datei in Cloud Storage hochzuladen. putBytes() verwendet ein byte[] und gibt ein UploadTask zurück, mit dem Sie den Status des Uploads verwalten und überwachen können.
Kotlin
// Get the data from an ImageView as bytes imageView.isDrawingCacheEnabled = true imageView.buildDrawingCache() val bitmap = (imageView.drawable as BitmapDrawable).bitmap val baos = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos) val data = baos.toByteArray() var uploadTask = mountainsRef.putBytes(data) uploadTask.addOnFailureListener { // Handle unsuccessful uploads }.addOnSuccessListener { taskSnapshot -> // taskSnapshot.metadata contains file metadata such as size, content-type, etc. // ... }
Java
// Get the data from an ImageView as bytes imageView.setDrawingCacheEnabled(true); imageView.buildDrawingCache(); Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); byte[] data = baos.toByteArray(); UploadTask uploadTask = mountainsRef.putBytes(data); uploadTask.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle unsuccessful uploads } }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc. // ... } });
Da putBytes() einen byte[] akzeptiert, muss Ihre Anwendung den gesamten Inhalt einer Datei auf einmal im Arbeitsspeicher halten. Verwenden Sie putStream() oder putFile(), um weniger Arbeitsspeicher zu belegen.
Aus einem Stream hochladen
Die Methode putStream() ist die vielseitigste Möglichkeit, eine Datei in Cloud Storage hochzuladen. putStream() verwendet ein InputStream und gibt ein UploadTask zurück, mit dem Sie den Status des Uploads verwalten und überwachen können.
Kotlin
val stream = FileInputStream(File("path/to/images/rivers.jpg")) uploadTask = mountainsRef.putStream(stream) uploadTask.addOnFailureListener { // Handle unsuccessful uploads }.addOnSuccessListener { taskSnapshot -> // taskSnapshot.metadata contains file metadata such as size, content-type, etc. // ... }
Java
InputStream stream = new FileInputStream(new File("path/to/images/rivers.jpg")); uploadTask = mountainsRef.putStream(stream); uploadTask.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle unsuccessful uploads } }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc. // ... } });
Aus einer lokalen Datei hochladen
Mit der Methode putFile() können Sie lokale Dateien auf dem Gerät hochladen, z. B. Fotos und Videos von der Kamera. putFile() verwendet ein File und gibt ein UploadTask zurück, mit dem Sie den Status des Uploads verwalten und überwachen können.
Kotlin
var file = Uri.fromFile(File("path/to/images/rivers.jpg")) val riversRef = storageRef.child("images/${file.lastPathSegment}") uploadTask = riversRef.putFile(file) // Register observers to listen for when the download is done or if it fails uploadTask.addOnFailureListener { // Handle unsuccessful uploads }.addOnSuccessListener { taskSnapshot -> // taskSnapshot.metadata contains file metadata such as size, content-type, etc. // ... }
Java
Uri file = Uri.fromFile(new File("path/to/images/rivers.jpg")); StorageReference riversRef = storageRef.child("images/"+file.getLastPathSegment()); uploadTask = riversRef.putFile(file); // Register observers to listen for when the download is done or if it fails uploadTask.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle unsuccessful uploads } }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { // taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc. // ... } });
Download-URL abrufen
Nachdem Sie eine Datei hochgeladen haben, können Sie eine URL zum Herunterladen der Datei abrufen. Rufen Sie dazu die Methode getDownloadUrl() für StorageReference auf:
Kotlin
val ref = storageRef.child("images/mountains.jpg") uploadTask = ref.putFile(file) val urlTask = uploadTask.continueWithTask { task -> if (!task.isSuccessful) { task.exception?.let { throw it } } ref.downloadUrl }.addOnCompleteListener { task -> if (task.isSuccessful) { val downloadUri = task.result } else { // Handle failures // ... } }
Java
final StorageReference ref = storageRef.child("images/mountains.jpg"); uploadTask = ref.putFile(file); Task<Uri> urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() { @Override public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception { if (!task.isSuccessful()) { throw task.getException(); } // Continue with the task to get the download URL return ref.getDownloadUrl(); } }).addOnCompleteListener(new OnCompleteListener<Uri>() { @Override public void onComplete(@NonNull Task<Uri> task) { if (task.isSuccessful()) { Uri downloadUri = task.getResult(); } else { // Handle failures // ... } } });
Dateimetadaten hinzufügen
Sie können beim Hochladen von Dateien auch Metadaten angeben.
Diese Metadaten enthalten typische Metadatenattribute für Dateien wie name, size und contentType (allgemein als MIME-Typ bezeichnet). Die Methode putFile() leitet den MIME-Typ automatisch aus der Erweiterung File ab. Sie können den automatisch erkannten Typ jedoch überschreiben, indem Sie contentType in den Metadaten angeben. Wenn Sie keinen contentType angeben und Cloud Storage keinen Standardwert aus der Dateiendung ableiten kann, verwendet Cloud Storage application/octet-stream. Weitere Informationen zu Dateimetadaten finden Sie im Abschnitt Dateimetadaten verwenden.
Kotlin
// Create file metadata including the content type var metadata = storageMetadata { contentType = "image/jpg" } // Upload the file and metadata uploadTask = storageRef.child("images/mountains.jpg").putFile(file, metadata)
Java
// Create file metadata including the content type StorageMetadata metadata = new StorageMetadata.Builder() .setContentType("image/jpg") .build(); // Upload the file and metadata uploadTask = storageRef.child("images/mountains.jpg").putFile(file, metadata);
Uploads verwalten
Zusätzlich zum Starten von Uploads können Sie Uploads mit den Methoden pause(), resume() und cancel() pausieren, fortsetzen und abbrechen. Pausierungs- und Fortsetzungsereignisse lösen die Statusänderungen pause bzw. progress aus. Wenn Sie einen Upload abbrechen, schlägt er mit einem Fehler fehl, der darauf hinweist, dass der Upload abgebrochen wurde.
Kotlin
uploadTask = storageRef.child("images/mountains.jpg").putFile(file) // Pause the upload uploadTask.pause() // Resume the upload uploadTask.resume() // Cancel the upload uploadTask.cancel()
Java
uploadTask = storageRef.child("images/mountains.jpg").putFile(file); // Pause the upload uploadTask.pause(); // Resume the upload uploadTask.resume(); // Cancel the upload uploadTask.cancel();
Uploadfortschritt im Blick behalten
Sie können Listener hinzufügen, um erfolgreiche, fehlgeschlagene, laufende oder pausierte Upload-Aufgaben zu verarbeiten:
| Listener-Typ | Typische Verwendung |
|---|---|
OnProgressListener |
Dieser Listener wird während der Datenübertragung regelmäßig aufgerufen und kann verwendet werden, um eine Upload-/Download-Anzeige zu füllen. |
OnPausedListener |
Dieser Listener wird immer dann aufgerufen, wenn die Aufgabe pausiert wird. |
OnSuccessListener |
Dieser Listener wird aufgerufen, wenn die Aufgabe erfolgreich abgeschlossen wurde. |
OnFailureListener |
Dieser Listener wird immer dann aufgerufen, wenn der Upload fehlgeschlagen ist. Dies kann aufgrund von Netzwerk-Timeouts, Autorisierungsfehlern oder wenn Sie die Aufgabe abbrechen, passieren. |
OnFailureListener wird mit einer Exception-Instanz aufgerufen. Andere Listener werden mit einem UploadTask.TaskSnapshot-Objekt aufgerufen.
Dieses Objekt ist eine unveränderliche Ansicht der Aufgabe zum Zeitpunkt des Ereignisses.
Ein UploadTask.TaskSnapshot enthält die folgenden Attribute:
| Attribut | Typ | Beschreibung |
|---|---|---|
getDownloadUrl |
String |
Eine URL, über die das Objekt heruntergeladen werden kann. Dies ist eine öffentliche, nicht erratbare URL, die für andere Clients freigegeben werden kann. Dieser Wert wird ausgefüllt, sobald ein Upload abgeschlossen ist. |
getError |
Exception |
Wenn die Aufgabe fehlgeschlagen ist, wird hier die Ursache als Ausnahme angegeben. |
getBytesTransferred |
long |
Die Gesamtzahl der Byte, die übertragen wurden, als dieser Snapshot erstellt wurde. |
getTotalByteCount |
long |
Die Gesamtzahl der Bytes, die voraussichtlich hochgeladen werden. |
getUploadSessionUri |
String |
Ein URI, der verwendet werden kann, um diese Aufgabe über einen weiteren Aufruf von „putFile“ fortzusetzen. |
getMetadata |
StorageMetadata |
Bevor ein Upload abgeschlossen ist, werden diese Metadaten an den Server gesendet. Nach Abschluss des Uploads werden diese Metadaten vom Server zurückgegeben. |
getTask |
UploadTask |
Die Aufgabe, mit der dieser Snapshot erstellt wurde. Mit dieser Aufgabe können Sie den Upload abbrechen, pausieren oder fortsetzen. |
getStorage |
StorageReference |
Die StorageReference, die zum Erstellen der UploadTask verwendet wurde. |
Die UploadTask-Ereignis-Listener bieten eine einfache und leistungsstarke Möglichkeit, Upload-Ereignisse zu überwachen.
Kotlin
// Observe state change events such as progress, pause, and resume // You'll need to import com.google.firebase.storage.component1 and // com.google.firebase.storage.component2 uploadTask.addOnProgressListener { (bytesTransferred, totalByteCount) -> val progress = (100.0 * bytesTransferred) / totalByteCount Log.d(TAG, "Upload is $progress% done") }.addOnPausedListener { Log.d(TAG, "Upload is paused") }
Java
// Observe state change events such as progress, pause, and resume uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount(); Log.d(TAG, "Upload is " + progress + "% done"); } }).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() { @Override public void onPaused(UploadTask.TaskSnapshot taskSnapshot) { Log.d(TAG, "Upload is paused"); } });
Änderungen am Aktivitätslebenszyklus verarbeiten
Uploads werden auch nach Änderungen am Aktivitätslebenszyklus im Hintergrund fortgesetzt, z. B. wenn ein Dialogfeld angezeigt oder der Bildschirm gedreht wird. Alle Listener, die Sie angehängt haben, bleiben ebenfalls angehängt. Dies kann zu unerwarteten Ergebnissen führen, wenn sie nach dem Beenden der Aktivität aufgerufen werden.
Sie können dieses Problem beheben, indem Sie Ihre Listener mit einem Aktivitätsbereich abonnieren, damit sie automatisch abgemeldet werden, wenn die Aktivität beendet wird. Verwenden Sie dann die Methode getActiveUploadTasks, wenn die Aktivität neu gestartet wird, um Upload-Aufgaben abzurufen, die noch ausgeführt werden oder vor Kurzem abgeschlossen wurden.
Das folgende Beispiel veranschaulicht dies und zeigt auch, wie der verwendete Speicherreferenzpfad beibehalten wird.
Kotlin
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) // If there's an upload in progress, save the reference so you can query it later outState.putString("reference", storageRef.toString()) } override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) // If there was an upload in progress, get its reference and create a new StorageReference val stringRef = savedInstanceState.getString("reference") ?: return storageRef = Firebase.storage.getReferenceFromUrl(stringRef) // Find all UploadTasks under this StorageReference (in this example, there should be one) val tasks = storageRef.activeUploadTasks if (tasks.size > 0) { // Get the task monitoring the upload val task = tasks[0] // Add new listeners to the task using an Activity scope task.addOnSuccessListener(this) { // Success! // ... } } }
Java
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // If there's an upload in progress, save the reference so you can query it later if (mStorageRef != null) { outState.putString("reference", mStorageRef.toString()); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // If there was an upload in progress, get its reference and create a new StorageReference final String stringRef = savedInstanceState.getString("reference"); if (stringRef == null) { return; } mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(stringRef); // Find all UploadTasks under this StorageReference (in this example, there should be one) List<UploadTask> tasks = mStorageRef.getActiveUploadTasks(); if (tasks.size() > 0) { // Get the task monitoring the upload UploadTask task = tasks.get(0); // Add new listeners to the task using an Activity scope task.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot state) { // Success! // ... } }); } }
getActiveUploadTasks ruft alle aktiven Uploadaufgaben unter der angegebenen Referenz ab. Möglicherweise müssen Sie also mehrere Aufgaben verarbeiten.
Uploads nach Prozessneustarts fortsetzen
Wenn der Prozess beendet wird, werden alle laufenden Uploads unterbrochen. Sie können den Upload jedoch fortsetzen, sobald der Vorgang neu gestartet wird, indem Sie die Uploadsitzung mit dem Server fortsetzen. So können Sie Zeit und Bandbreite sparen, da der Upload nicht am Anfang der Datei gestartet wird.
Starten Sie dazu den Upload über putFile. Rufe für das resultierende StorageTask getUploadSessionUri auf und speichere den resultierenden Wert in einem nichtflüchtigen Speicher (z. B. SharedPreferences).
Kotlin
uploadTask = storageRef.putFile(localFile) uploadTask.addOnProgressListener { taskSnapshot -> sessionUri = taskSnapshot.uploadSessionUri if (sessionUri != null && !saved) { saved = true // A persisted session has begun with the server. // Save this to persistent storage in case the process dies. } }
Java
uploadTask = mStorageRef.putFile(localFile); uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { Uri sessionUri = taskSnapshot.getUploadSessionUri(); if (sessionUri != null && !mSaved) { mSaved = true; // A persisted session has begun with the server. // Save this to persistent storage in case the process dies. } } });
Nachdem der Prozess mit einem unterbrochenen Upload neu gestartet wurde, rufen Sie „putFile“ noch einmal auf. Übergeben Sie dieses Mal aber auch den gespeicherten URI.
Kotlin
// resume the upload task from where it left off when the process died. // to do this, pass the sessionUri as the last parameter uploadTask = storageRef.putFile( localFile, storageMetadata { }, sessionUri, )
Java
//resume the upload task from where it left off when the process died. //to do this, pass the sessionUri as the last parameter uploadTask = mStorageRef.putFile(localFile, new StorageMetadata.Builder().build(), sessionUri);
Sitzungen dauern eine Woche. Wenn Sie versuchen, eine Sitzung fortzusetzen, nachdem sie abgelaufen ist oder ein Fehler aufgetreten ist, erhalten Sie einen Fehler-Callback. Es liegt in Ihrer Verantwortung, dafür zu sorgen, dass sich die Datei zwischen den Uploads nicht geändert hat.
Fehlerbehandlung
Es gibt eine Reihe von Gründen, warum beim Hochladen Fehler auftreten können, z. B. weil die lokale Datei nicht vorhanden ist oder der Nutzer keine Berechtigung zum Hochladen der gewünschten Datei hat. Weitere Informationen zu Fehlern finden Sie im Abschnitt Fehler verarbeiten der Dokumentation.
Vollständiges Beispiel
Im Folgenden finden Sie ein vollständiges Beispiel für einen Upload mit Fortschrittsüberwachung und Fehlerbehandlung:
Kotlin
// File or Blob file = Uri.fromFile(File("path/to/mountains.jpg")) // Create the file metadata metadata = storageMetadata { contentType = "image/jpeg" } // Upload file and metadata to the path 'images/mountains.jpg' uploadTask = storageRef.child("images/${file.lastPathSegment}").putFile(file, metadata) // Listen for state changes, errors, and completion of the upload. // You'll need to import com.google.firebase.storage.component1 and // com.google.firebase.storage.component2 uploadTask.addOnProgressListener { (bytesTransferred, totalByteCount) -> val progress = (100.0 * bytesTransferred) / totalByteCount Log.d(TAG, "Upload is $progress% done") }.addOnPausedListener { Log.d(TAG, "Upload is paused") }.addOnFailureListener { // Handle unsuccessful uploads }.addOnSuccessListener { // Handle successful uploads on complete // ... }
Java
// File or Blob file = Uri.fromFile(new File("path/to/mountains.jpg")); // Create the file metadata metadata = new StorageMetadata.Builder() .setContentType("image/jpeg") .build(); // Upload file and metadata to the path 'images/mountains.jpg' uploadTask = storageRef.child("images/"+file.getLastPathSegment()).putFile(file, metadata); // Listen for state changes, errors, and completion of the upload. uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount(); Log.d(TAG, "Upload is " + progress + "% done"); } }).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() { @Override public void onPaused(UploadTask.TaskSnapshot taskSnapshot) { Log.d(TAG, "Upload is paused"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle unsuccessful uploads } }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { // Handle successful uploads on complete // ... } });
Nachdem Sie Dateien hochgeladen haben, erfahren Sie jetzt, wie Sie sie aus Cloud Storage herunterladen.