Kotlin - Firebase和Glide - 获取图片URL以便Glide可以使用

3

我在从Firebase存储获取图像URL方面遇到了困难,我已经从数据库中获取了照片URL,但是我知道,Glide不能从这样的链接获取图片: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()

to

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!!)
            }
        }
    }
}
1个回答

1
将您的 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:
 val photoUrl = it

在“onSuccess(it.result!!)”中,它给了我类型不匹配的错误 - 需要Uploadtask.TaskSnapshot?找到:Uri? - Renato Lulic
但我相信应该是Uri,但不知道我哪里出了错... - Renato Lulic
1
@RenatoLulic请检查我的编辑答案。如果出现任何语法错误,请告诉我。 - Amit Tiwary
非常感谢啊!现在可以用了:)我为这个问题苦恼了好几天,真的很感激! - Renato Lulic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接