Mit Cloud Storage for Firebase können Sie Dateien schnell und einfach in einen von Firebase bereitgestellten und verwalteten Cloud Storage- Bucket hochladen.
Daten hochladen
Um eine Datei in Cloud Storage hochzuladen, erstellen Sie zunächst einen Verweis auf den vollständigen Pfad der Datei, einschließlich des Dateinamens.
Kotlin+KTX
// 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. Ihre Referenz muss auf eine untergeordnete URL verweisen.
Hochladen von Daten im Speicher
Die Methode putBytes()
ist die einfachste Möglichkeit, eine Datei in Cloud Storage hochzuladen. putBytes()
nimmt ein byte[]
und gibt eine UploadTask
zurück, die Sie verwenden können, um den Status des Uploads zu verwalten und zu überwachen.
Kotlin+KTX
// 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()
ein byte[]
akzeptiert, muss Ihre App den gesamten Inhalt einer Datei auf einmal im Arbeitsspeicher halten. Erwägen Sie die Verwendung von putStream()
oder putFile()
, um weniger Speicher zu verbrauchen.
Aus einem Stream hochladen
Die Methode putStream()
ist die vielseitigste Methode zum Hochladen einer Datei in Cloud Storage. putStream()
nimmt einen InputStream
und gibt eine UploadTask
zurück, die Sie verwenden können, um den Status des Uploads zu verwalten und zu überwachen.
Kotlin+KTX
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 das Gerät hochladen, z. B. Fotos und Videos von der Kamera. putFile()
nimmt eine File
und gibt eine UploadTask
zurück, die Sie verwenden können, um den Status des Uploads zu verwalten und zu überwachen.
Kotlin+KTX
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. // ... } });
Holen Sie sich eine Download-URL
Nach dem Hochladen einer Datei können Sie eine URL zum Herunterladen der Datei abrufen, indem Sie die Methode getDownloadUrl()
für StorageReference
aufrufen:
Kotlin+KTX
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 einbeziehen. Diese Metadaten enthalten typische Dateimetadateneigenschaften wie name
, size
und contentType
(allgemein als MIME-Typ bezeichnet). Die putFile()
Methode leitet den MIME-Typ automatisch von der File
ab, aber Sie können den automatisch erkannten Typ überschreiben, indem Sie contentType
in den Metadaten angeben. Wenn Sie keinen contentType
angeben und Cloud Storage aus der Dateierweiterung keinen Standardwert ableiten kann, verwendet Cloud Storage application/octet-stream
. Weitere Informationen zu Dateimetadaten finden Sie im Abschnitt Dateimetadaten verwenden .
Kotlin+KTX
// 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()
anhalten, fortsetzen und abbrechen. Pause- und Resume-Ereignisse lösen pause
bzw. progress
aus. Das Abbrechen eines Uploads führt dazu, dass der Upload mit einem Fehler fehlschlägt, der angibt, dass der Upload abgebrochen wurde.
Kotlin+KTX
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();
Überwachen Sie den Upload-Fortschritt
Sie können Listener hinzufügen, um Erfolg, Fehler, Fortschritt oder Pausen in Ihrer Upload-Aufgabe zu verarbeiten:
Listener-Typ | Typische Verwendung |
---|---|
OnProgressListener | Dieser Listener wird regelmäßig aufgerufen, wenn Daten übertragen werden, und kann verwendet werden, um einen Upload/Download-Indikator zu füllen. |
OnPausedListener | Dieser Listener wird jedes Mal aufgerufen, wenn die Aufgabe angehalten wird. |
OnSuccessListener | Dieser Listener wird aufgerufen, wenn die Aufgabe erfolgreich abgeschlossen wurde. |
OnFailureListener | Dieser Listener wird jedes Mal aufgerufen, wenn der Upload fehlgeschlagen ist. Dies kann aufgrund von Netzwerkzeitüberschreitungen, Autorisierungsfehlern oder dem Abbrechen der Aufgabe geschehen. |
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 Eintretens des Ereignisses. Ein UploadTask.TaskSnapshot
enthält die folgenden Eigenschaften:
Eigentum | Typ | Beschreibung |
---|---|---|
getDownloadUrl | String | Eine URL, die zum Herunterladen des Objekts verwendet werden kann. Dies ist eine öffentliche, nicht zu erratende URL, die mit anderen Clients geteilt werden kann. Dieser Wert wird ausgefüllt, sobald ein Upload abgeschlossen ist. |
getError | Exception | Wenn die Aufgabe fehlgeschlagen ist, wird dies die Ursache als Ausnahme haben. |
getBytesTransferred | long | Die Gesamtzahl der Bytes, die übertragen wurden, als dieser Snapshot erstellt wurde. |
getTotalByteCount | long | Die Gesamtzahl der Bytes, die hochgeladen werden sollen. |
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, sind dies die Metadaten, die an den Server gesendet werden. Nach Abschluss des Uploads sind dies die vom Server zurückgegebenen Metadaten. |
getTask | UploadTask | Die Aufgabe, die diesen Snapshot erstellt hat. Verwenden Sie diese Aufgabe, um den Upload abzubrechen, anzuhalten oder fortzusetzen. |
getStorage | StorageReference | Die zum Erstellen der UploadTask verwendete StorageReference . |
Die UploadTask
Ereignis-Listener bieten eine einfache und leistungsstarke Möglichkeit, Upload-Ereignisse zu überwachen.
Kotlin+KTX
// Observe state change events such as progress, pause, and resume // You'll need to import com.google.firebase.storage.ktx.component1 and // com.google.firebase.storage.ktx.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"); } });
Behandeln Sie Änderungen im Aktivitätslebenszyklus
Uploads werden auch nach Änderungen des Aktivitätslebenszyklus (z. B. Anzeigen eines Dialogfelds oder Drehen des Bildschirms) im Hintergrund fortgesetzt. Alle Zuhörer, die Sie angehängt hatten, bleiben ebenfalls angehängt. Dies kann zu unerwarteten Ergebnissen führen, wenn sie angerufen werden, nachdem die Aktivität beendet wurde.
Sie können dieses Problem lösen, indem Sie Ihre Zuhörer mit einem Aktivitätsbereich abonnieren, um sie automatisch abzumelden, wenn die Aktivität endet. Verwenden Sie dann die getActiveUploadTasks
Methode, wenn die Aktivität neu gestartet wird, um Upload-Aufgaben abzurufen, die noch ausgeführt werden oder kürzlich abgeschlossen wurden.
Das folgende Beispiel demonstriert dies und zeigt auch, wie der verwendete Speicherreferenzpfad beibehalten wird.
Kotlin+KTX
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 Upload-Aufgaben an und unterhalb der bereitgestellten Referenz ab, sodass Sie möglicherweise mehrere Aufgaben bearbeiten müssen.
Fortsetzen von Uploads über Prozessneustarts hinweg
Wenn Ihr Prozess heruntergefahren wird, werden alle laufenden Uploads unterbrochen. Sie können jedoch mit dem Hochladen fortfahren, sobald der Prozess neu gestartet wird, indem Sie die Upload-Sitzung mit dem Server fortsetzen. Dies kann Zeit und Bandbreite sparen, da der Upload nicht am Anfang der Datei beginnt.
Beginnen Sie dazu mit dem Hochladen über putFile
. Rufen Sie für die resultierende StorageTask
getUploadSessionUri
auf und speichern Sie den resultierenden Wert im dauerhaften Speicher (z. B. SharedPreferences).
Kotlin+KTX
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 Ihr Prozess mit einem unterbrochenen Upload neu gestartet wurde, rufen Sie putFile erneut auf. Diesmal aber auch am geretteten Uri vorbei.
Kotlin+KTX
// 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 Fehlerrückruf. Es liegt in Ihrer Verantwortung sicherzustellen, dass sich die Datei zwischen den Uploads nicht verändert hat.
Fehlerbehandlung
Es gibt eine Reihe von Gründen, warum beim Hochladen Fehler auftreten können, darunter die lokale Datei, die nicht vorhanden ist, oder der Benutzer, der keine Berechtigung zum Hochladen der gewünschten Datei hat. Weitere Informationen zu Fehlern finden Sie im Abschnitt Fehlerbehandlung der Dokumentation.
Vollständiges Beispiel
Ein vollständiges Beispiel eines Uploads mit Fortschrittsüberwachung und Fehlerbehandlung ist unten dargestellt:
Kotlin+KTX
// 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.ktx.component1 and // com.google.firebase.storage.ktx.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, wie Sie sie aus Cloud Storage herunterladen .