本文概述
Cloud Storage为开发人员提供了方便快捷地将文件上传到由Firebase提供或管理的Google Cloud Storage存储桶的功能。默认情况下, 在Cloud Storage存储桶中上传文件时需要Firebase身份验证。但是我们可以修改Firebase安全规则, 以允许取消身份验证访问。
由于默认引擎应用, Google应用和Firebase共享此存储桶, 因此配置公共访问权限还可以使新上传的App Engine文件可以公开访问。设置身份验证时, 请确保再次访问我们的存储桶。
要将文件上传到Cloud Storage, 我们将首先创建对带有文件名的文件完整路径的引用。
// 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")
//When the file names are same, the references point to different files
mountainsRef.name == mountainImagesRef.name // true
mountainsRef.path == mountainImagesRef.path // false
创建适当的引用后, 我们将调用putBytes(), putFile()或putStream()方法将文件上传到Cloud Storage。我们无法参考Google Cloud Storage存储桶的根目录上传数据。我们的参考必须指向子URL。
从内存中的数据上传
putBytes()方法是最轻松地将文件上传到Cloud Storage的最简单方法。 putBytes()方法使用byte []并返回一个UploadTask, 我们可以使用它来管理和监视上载的状态。
// Getting 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 {
// Handlling unsuccessful uploads
}.addOnSuccessListener {
// The taskSnapshot.metadata contains file metadata such as content-type, size, etc.
// ...
}
由于putBytes()接受byte [], 因此它要求我们的应用一次将文件的全部内容保存在内存中。我们认为putStream()或putFile()使用较少的内存。
从流上传
将文件上传到Cloud Storage的最灵活方法是使用putStream()方法。此方法采用InputStream并返回一个UploadTask, 它将用于管理和监视上载的状态。
val stream = FileInputStream(File("path/to/images/mountain.jpg"))
uploadTask = mountainsRef.putStream(stream)
uploadTask.addOnFailureListener {
// Handling unsuccessful uploads
}.addOnSuccessListener {
// The taskSnapshot.metadata contains file metadata such as content-type, size, etc.
// ...
}
从本地文件上传
我们可以使用putFile()方法将本地文件上传到设备上。此方法将File作为输入, 并返回一个UploadTask, 我们可以使用它来管理和监视上载的状态。
var file = Uri.fromFile(File("path/to/images/rivers.jpg"))
val riversRef = storageRef.child("images/${file.lastPathSegment}")
uploadTask = riversRef.putFile(file)
// Registering observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener {
// Handling unsuccessful uploads
}.addOnSuccessListener {
// The taskSnapshot.metadata contains file metadata such as content-type, size, etc.
// ...
}
上传后获取下载网址
要下载文件, 需要我们有一个URL。为了获取URL, 我们必须在StorageReference上调用getDownloadUrl()方法。
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 {
// Handling failures
// ...
}
}
管理上传
还有一些其他可用的方法, 例如pause(), resume()和cancel(), 可用于暂停, 恢复或取消上载。在暂停和恢复事件中, 暂停和进度状态分别发生变化。取消上载会导致上载失败, 并显示一个错误, 指示上载已被取消。
uploadTask = storageRef.child("images/mountains.jpg").putFile(file)
// Pausing the upload
uploadTask.pause()
// Resuming the upload
uploadTask.resume()
// Canceling the upload
uploadTask.cancel()
完整的例子
带有进度监控和错误处理的上传示例如下:
// Getting File or Blob
file = Uri.fromFile(File("path/to/mountains.jpg"))
// Creating the file metadata
metadata = StorageMetadata.Builder()
.setContentType("image/jpeg")
.build()
// Uploading the file and the metadata to the path 'images/mountains.jpg'
uploadTask = storageRef.child("images/${file.lastPathSegment}").putFile(file, metadata)
// Listening for state changes, errors, and completion of the upload.
uploadTask.addOnProgressListener { taskSnapshot ->
val progress = (100.0 * taskSnapshot.bytesTransferred) / taskSnapshot.totalByteCount
println("Upload is $progress% done")
}.addOnPausedListener {
println("Upload is paused")
}.addOnFailureListener {
// Handling unsuccessful uploads
}.addOnSuccessListener {
// Handling successful uploads on complete
// ...
}
评论前必须登录!
注册