Kotlin - Firebase 和 Glide - 获取图像 url 以便 glide 可以使用它
Kotlin - Firebase and Glide - get image url so glide can use it
我很难从 firebase 存储中获取图像 URL,我从数据库中获取了照片 URL,但据我所知,Glide 无法从中获取图片link 像这样:com.google.firebase.storage.UploadTask@62873ce
这是我的存储和数据库参考资料:
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (UploadTask.TaskSnapshot) -> Unit) {
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
mStorage.child("users/$uid/photo").downloadUrl.addOnCompleteListener { task ->
if (it.isSuccessful) {
onSuccess(it.result!!)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
private fun DatabaseReference.updateUserPhoto(uid: String, photoUrl: String,
onSuccess: () -> Unit){
child("users/$uid/photo").setValue(photoUrl)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
函数如下:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK) {
val uid = mAuth.currentUser!!.uid
mStorage.uploadUserPhoto(uid, mImageUri) {
val photoUrl = it.task.toString()
mDatabase.updateUserPhoto(uid, photoUrl) {
mUser = mUser.copy(photo = photoUrl)
profile_image.loadUserPhoto(mUser.photo)
}
}
}
}
我尝试更改
val photoUrl = it.task.toString()
至
val photoUrl = it.downloadUrl.toString()
但它突出显示 'downloadUrl' 为未解决的引用
完整代码:
package com.example.homeactivity.activities
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.Editable
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.example.homeactivity.R
import com.example.homeactivity.models.User
import com.example.homeactivity.views.PasswordDialog
import com.google.firebase.auth.AuthCredential
import com.google.firebase.auth.EmailAuthProvider
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.StorageReference
import com.google.firebase.storage.UploadTask
import kotlinx.android.synthetic.main.activity_edit_profile.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
class EditProfileActivity : AppCompatActivity(), PasswordDialog.Listener {
private lateinit var mImageUri: Uri
private lateinit var mStorage: StorageReference
private val TAG = "EditProfileActivity"
private lateinit var mUser: com.example.homeactivity.models.User
private lateinit var mAuth: FirebaseAuth
private lateinit var mDatabase: DatabaseReference
private lateinit var mPendingUser: com.example.homeactivity.models.User
private val TAKE_PICTURE_REQUEST_CODE = 1
val simpleDateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_profile)
Log.d(TAG, "onCreate")
close_image.setOnClickListener { finish() }
save_image.setOnClickListener { updateProfile() }
change_photo_text.setOnClickListener { takeCameraPicture() }
mAuth = FirebaseAuth.getInstance()
mDatabase = FirebaseDatabase.getInstance().reference
mStorage = FirebaseStorage.getInstance().reference
mDatabase.child("users").child(mAuth.currentUser!!.uid)
.addListenerForSingleValueEvent(ValueEventListenerAdapter {
mUser = it.getValue(com.example.homeactivity.models.User::class.java)!!
name_input.setText(mUser.name, TextView.BufferType.EDITABLE)
username_input.setText(mUser.username, TextView.BufferType.EDITABLE)
website_input.setText(mUser.website, TextView.BufferType.EDITABLE)
bio_input.setText(mUser.bio, TextView.BufferType.EDITABLE)
email_input.setText(mUser.email, TextView.BufferType.EDITABLE)
phone_input.setText(mUser.phone?.toString(), TextView.BufferType.EDITABLE)
profile_image.loadUserPhoto(mUser.photo)
})
}
private fun takeCameraPicture() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (intent.resolveActivity(packageManager) != null) {
val imageFile = createImageFile()
mImageUri = FileProvider.getUriForFile(
this,
"com.example.homeactivity.fileprovider",
imageFile
)
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri)
startActivityForResult(intent, TAKE_PICTURE_REQUEST_CODE)
}
}
private fun createImageFile(): File {
val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${simpleDateFormat.format(Date())}_",
".jpg",
storageDir
)
}
@SuppressLint("MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK) {
val uid = mAuth.currentUser!!.uid
mStorage.uploadUserPhoto(uid, mImageUri) {
val photoUrl = it.task.toString()
mDatabase.updateUserPhoto(uid, photoUrl) {
mUser = mUser.copy(photo = photoUrl)
profile_image.loadUserPhoto(mUser.photo)
}
}
}
}
private fun updateProfile() {
mPendingUser = readInputs()
val error = validate(mPendingUser)
if (error == null) {
if (mPendingUser.email == mUser.email) {
updateUser(mPendingUser)
} else {
PasswordDialog().show(supportFragmentManager, "password_dialog")
}
} else {
showToast(error)
}
}
private fun readInputs(): User {
return User(
name = name_input.text.toString(),
username = username_input.text.toString(),
email = email_input.text.toString(),
website = website_input.text.toStringOrNull(),
bio = bio_input.text.toStringOrNull(),
phone = phone_input.text.toStringOrNull()
)
}
override fun onPasswordConfirm(password: String) {
if (password.isNotEmpty()) {
val credential = EmailAuthProvider.getCredential(mUser.email, password)
mAuth.currentUser!!.reauthenticate(credential) {
mAuth.currentUser!!.updateEmail(mPendingUser.email) {
updateUser(mPendingUser)
}
}
} else {
showToast("You must enter your password")
}
}
private fun updateUser(user: com.example.homeactivity.models.User) {
val updatesMap = mutableMapOf<String, Any?>()
if (user.name != mUser.name) updatesMap["name"] = user.name
if (user.username != mUser.username) updatesMap["username"] = user.username
if (user.website != mUser.website) updatesMap["website"] = user.website
if (user.bio != mUser.bio) updatesMap["bio"] = user.bio
if (user.email != mUser.email) updatesMap["email"] = user.email
if (user.phone != mUser.phone) updatesMap["phone"] = user.phone
mDatabase.updateUser(mAuth.currentUser!!.uid, updatesMap) {
showToast("Profile saved")
finish()
}
}
private fun validate(user: com.example.homeactivity.models.User): String? =
when {
user.name.isEmpty() -> "Please enter name"
user.username.isEmpty() -> "Please enter username"
user.email.isEmpty() -> "Please enter email"
else -> null
}
private fun FirebaseUser.updateEmail(email: String, onSuccess: () -> Unit) {
updateEmail(email).addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (UploadTask.TaskSnapshot) -> Unit) {
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
mStorage.child("users/$uid/photo").downloadUrl.addOnCompleteListener { task ->
if (it.isSuccessful) {
onSuccess(it.result!!)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
private fun DatabaseReference.updateUserPhoto(uid: String, photoUrl: String,
onSuccess: () -> Unit){
child("users/$uid/photo").setValue(photoUrl)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun DatabaseReference.updateUser(
uid: String, updates: Map<String, Any?>,
onSuccess: () -> Unit
) {
child("users").child(uid).updateChildren(updates)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun FirebaseUser.reauthenticate(credential: AuthCredential, onSuccess: () -> Unit) {
reauthenticate(credential).addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
}
像这样更改您的 uploadUserPhoto 方法
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (String) -> Unit) {
val uTask = mStorage.child("users/$uid/photo").putFile(mImageUri)
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
uTask.continueWithTask { task ->
mStorage.child("users/$uid/photo").downloadUrl
}.addOnCompleteListener{
if (it.isSuccessful && it.result != null) {
onSuccess(it.result!!.toString)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
在你的 onActivityResult 中使用 url like
val photoUrl = it
我很难从 firebase 存储中获取图像 URL,我从数据库中获取了照片 URL,但据我所知,Glide 无法从中获取图片link 像这样:com.google.firebase.storage.UploadTask@62873ce
这是我的存储和数据库参考资料:
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (UploadTask.TaskSnapshot) -> Unit) {
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
mStorage.child("users/$uid/photo").downloadUrl.addOnCompleteListener { task ->
if (it.isSuccessful) {
onSuccess(it.result!!)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
private fun DatabaseReference.updateUserPhoto(uid: String, photoUrl: String,
onSuccess: () -> Unit){
child("users/$uid/photo").setValue(photoUrl)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
函数如下:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK) {
val uid = mAuth.currentUser!!.uid
mStorage.uploadUserPhoto(uid, mImageUri) {
val photoUrl = it.task.toString()
mDatabase.updateUserPhoto(uid, photoUrl) {
mUser = mUser.copy(photo = photoUrl)
profile_image.loadUserPhoto(mUser.photo)
}
}
}
}
我尝试更改
val photoUrl = it.task.toString()
至
val photoUrl = it.downloadUrl.toString()
但它突出显示 'downloadUrl' 为未解决的引用
完整代码:
package com.example.homeactivity.activities
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.Editable
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.example.homeactivity.R
import com.example.homeactivity.models.User
import com.example.homeactivity.views.PasswordDialog
import com.google.firebase.auth.AuthCredential
import com.google.firebase.auth.EmailAuthProvider
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.StorageReference
import com.google.firebase.storage.UploadTask
import kotlinx.android.synthetic.main.activity_edit_profile.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
class EditProfileActivity : AppCompatActivity(), PasswordDialog.Listener {
private lateinit var mImageUri: Uri
private lateinit var mStorage: StorageReference
private val TAG = "EditProfileActivity"
private lateinit var mUser: com.example.homeactivity.models.User
private lateinit var mAuth: FirebaseAuth
private lateinit var mDatabase: DatabaseReference
private lateinit var mPendingUser: com.example.homeactivity.models.User
private val TAKE_PICTURE_REQUEST_CODE = 1
val simpleDateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_profile)
Log.d(TAG, "onCreate")
close_image.setOnClickListener { finish() }
save_image.setOnClickListener { updateProfile() }
change_photo_text.setOnClickListener { takeCameraPicture() }
mAuth = FirebaseAuth.getInstance()
mDatabase = FirebaseDatabase.getInstance().reference
mStorage = FirebaseStorage.getInstance().reference
mDatabase.child("users").child(mAuth.currentUser!!.uid)
.addListenerForSingleValueEvent(ValueEventListenerAdapter {
mUser = it.getValue(com.example.homeactivity.models.User::class.java)!!
name_input.setText(mUser.name, TextView.BufferType.EDITABLE)
username_input.setText(mUser.username, TextView.BufferType.EDITABLE)
website_input.setText(mUser.website, TextView.BufferType.EDITABLE)
bio_input.setText(mUser.bio, TextView.BufferType.EDITABLE)
email_input.setText(mUser.email, TextView.BufferType.EDITABLE)
phone_input.setText(mUser.phone?.toString(), TextView.BufferType.EDITABLE)
profile_image.loadUserPhoto(mUser.photo)
})
}
private fun takeCameraPicture() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (intent.resolveActivity(packageManager) != null) {
val imageFile = createImageFile()
mImageUri = FileProvider.getUriForFile(
this,
"com.example.homeactivity.fileprovider",
imageFile
)
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri)
startActivityForResult(intent, TAKE_PICTURE_REQUEST_CODE)
}
}
private fun createImageFile(): File {
val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${simpleDateFormat.format(Date())}_",
".jpg",
storageDir
)
}
@SuppressLint("MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK) {
val uid = mAuth.currentUser!!.uid
mStorage.uploadUserPhoto(uid, mImageUri) {
val photoUrl = it.task.toString()
mDatabase.updateUserPhoto(uid, photoUrl) {
mUser = mUser.copy(photo = photoUrl)
profile_image.loadUserPhoto(mUser.photo)
}
}
}
}
private fun updateProfile() {
mPendingUser = readInputs()
val error = validate(mPendingUser)
if (error == null) {
if (mPendingUser.email == mUser.email) {
updateUser(mPendingUser)
} else {
PasswordDialog().show(supportFragmentManager, "password_dialog")
}
} else {
showToast(error)
}
}
private fun readInputs(): User {
return User(
name = name_input.text.toString(),
username = username_input.text.toString(),
email = email_input.text.toString(),
website = website_input.text.toStringOrNull(),
bio = bio_input.text.toStringOrNull(),
phone = phone_input.text.toStringOrNull()
)
}
override fun onPasswordConfirm(password: String) {
if (password.isNotEmpty()) {
val credential = EmailAuthProvider.getCredential(mUser.email, password)
mAuth.currentUser!!.reauthenticate(credential) {
mAuth.currentUser!!.updateEmail(mPendingUser.email) {
updateUser(mPendingUser)
}
}
} else {
showToast("You must enter your password")
}
}
private fun updateUser(user: com.example.homeactivity.models.User) {
val updatesMap = mutableMapOf<String, Any?>()
if (user.name != mUser.name) updatesMap["name"] = user.name
if (user.username != mUser.username) updatesMap["username"] = user.username
if (user.website != mUser.website) updatesMap["website"] = user.website
if (user.bio != mUser.bio) updatesMap["bio"] = user.bio
if (user.email != mUser.email) updatesMap["email"] = user.email
if (user.phone != mUser.phone) updatesMap["phone"] = user.phone
mDatabase.updateUser(mAuth.currentUser!!.uid, updatesMap) {
showToast("Profile saved")
finish()
}
}
private fun validate(user: com.example.homeactivity.models.User): String? =
when {
user.name.isEmpty() -> "Please enter name"
user.username.isEmpty() -> "Please enter username"
user.email.isEmpty() -> "Please enter email"
else -> null
}
private fun FirebaseUser.updateEmail(email: String, onSuccess: () -> Unit) {
updateEmail(email).addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (UploadTask.TaskSnapshot) -> Unit) {
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
mStorage.child("users/$uid/photo").downloadUrl.addOnCompleteListener { task ->
if (it.isSuccessful) {
onSuccess(it.result!!)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
private fun DatabaseReference.updateUserPhoto(uid: String, photoUrl: String,
onSuccess: () -> Unit){
child("users/$uid/photo").setValue(photoUrl)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun DatabaseReference.updateUser(
uid: String, updates: Map<String, Any?>,
onSuccess: () -> Unit
) {
child("users").child(uid).updateChildren(updates)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun FirebaseUser.reauthenticate(credential: AuthCredential, onSuccess: () -> Unit) {
reauthenticate(credential).addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
}
像这样更改您的 uploadUserPhoto 方法
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (String) -> Unit) {
val uTask = mStorage.child("users/$uid/photo").putFile(mImageUri)
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
uTask.continueWithTask { task ->
mStorage.child("users/$uid/photo").downloadUrl
}.addOnCompleteListener{
if (it.isSuccessful && it.result != null) {
onSuccess(it.result!!.toString)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
在你的 onActivityResult 中使用 url like
val photoUrl = it