【问题标题】:Kotlin - Firebase - Save Uri to user's folder images keeps saving wrong UriKotlin - Firebase - 将 Uri 保存到用户的文件夹图像不断保存错误的 Uri
【发布时间】:2020-04-29 02:59:56
【问题描述】:

我正在尝试构建一个类似 Instagram 的应用程序,当我尝试将拍摄的照片保存到 Firebase 数据库上用户的“图像”文件夹时出现问题。它不断保存诸如“com.google.firebase.storage.UploadTask@62873ce”之类的内容

而不是这样的链接: "https://firebasestorage.googleapis.com/v0/b/gramgram-1b3f9.appspot.com/o/users%2F7q3pqR6GnHMx7NSdgoBqZETkrS32%2Fphoto?alt=media&token=bbcbe556-1de5-4176-aba2-599f829e65"

这是我的分享活动.kt

class ShareActivity : BaseActivity(2) {
    private val TAG = "ShareActivity"
    private lateinit var mCamera: CameraHelper
    private lateinit var mFirebase: FirebaseHelper


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_share)
        Log.d(TAG, "onCreate")

        mFirebase =FirebaseHelper(this)

        mCamera = CameraHelper(this)
        mCamera.takeCameraPicture()

        back_image.setOnClickListener{finish()}
        share_text.setOnClickListener{share()}
    }


    @SuppressLint("MissingSuperCall")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == mCamera.REQUEST_CODE){
            if (resultCode == RESULT_OK){
                GlideApp.with(this).load(mCamera.imageUri).centerCrop().into(post_image)
            } else{
                finish()
            }
        }
    }

    private fun share(){
        val imageUri = mCamera.imageUri
        if (imageUri != null){
            val uid = mFirebase.auth.currentUser!!.uid
            mFirebase.storage.child("users").child(uid).child("images")
                .child(imageUri.lastPathSegment!!).putFile(imageUri).addOnCompleteListener {
                    if (it.isSuccessful){
                        mFirebase.database.child("images").child(uid).push()
                            .setValue(it.toString())
                            .addOnCompleteListener{
                                if (it.isSuccessful){
                                    startActivity(Intent(this,
                                        ProfileActivity::class.java))
                                    finish()
                                } else {
                                    showToast(it.exception!!.message!!)
                                }
                            }
                    } else {
                        showToast(it.exception!!.message!!)
                    }
                }
        }
    }
}

这是我在 FirebaseHelper.kt 中的 uploadUserPhoto 和 updateUsePhoto 函数

fun uploadUserPhoto(photo: Uri, onSuccess: (String) -> Unit) {
    val uTask = storage.child("users/${auth.currentUser!!.uid}/photo").putFile(photo)
        storage.child("users/${auth.currentUser!!.uid}/photo").putFile(photo)
            .addOnCompleteListener {
        if (it.isSuccessful) {
            uTask.continueWithTask { _ ->
                storage.child("users/${auth.currentUser!!.uid}/photo").downloadUrl
            }.addOnCompleteListener{
                if (it.isSuccessful && it.result != null) {
                    onSuccess(it.result.toString())
                } else {
                    activity.showToast(it.exception!!.message!!)
                }
            }
        }
    }
}


fun updateUserPhoto( photoUrl: String, onSuccess: () -> Unit){
    database.child("users/${auth.currentUser!!.uid}/photo").setValue(photoUrl)
        .addOnCompleteListener {
            if (it.isSuccessful) {
                onSuccess()
            } else {
                activity.showToast(it.exception!!.message!!)
            }
        }
}

我不确定如何设置我的private fun share() 以将正确的 URL 上传到用户的“图像”文件夹

这是我的 CameraHelper.kt

class CameraHelper(private val activity: Activity){
var imageUri: Uri? = null
val REQUEST_CODE = 1
private val simpleDateFormat = SimpleDateFormat(
    "yyyyMMdd_HHmmss",
    Locale.US
)

fun takeCameraPicture() {
    val intent =
        Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    if (intent.resolveActivity(activity.packageManager) != null) {
        val imageFile = createImageFile()
        imageUri = FileProvider.getUriForFile(
            activity,
            "com.example.homeactivity.fileprovider",
            imageFile
        )
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
        activity.startActivityForResult(intent, REQUEST_CODE)
    }
}

private fun createImageFile(): File {
    val storageDir: File? = activity.getExternalFilesDir(
        Environment.DIRECTORY_PICTURES
    )
    return File.createTempFile(
        "JPEG_${simpleDateFormat.format(Date())}_",
        ".jpg",
        storageDir
    )
}

}

【问题讨论】:

  • setValue(it.toString()) -- it 我想是你的UploadTask。我已经有大约一年没有使用 Firebase 实时数据库了,但我怀疑你是否会在 UploadTask 上调用 toString() 来获取 URL。
  • 你在哪里调用uploadUserPhoto?
  • 试过了,它使应用程序崩溃并给出 com.google.firebase.database.DatabaseException: Found conflicting getter for name: getResult @CommonsWare
  • @DougStevenson 我在另一个函数中调用它来上传个人资料图片,但我分享了这段代码只是为了让你们看到代码正常工作,我不知道如何设置我的私人有趣的 share() 像这样工作

标签: android firebase kotlin firebase-realtime-database firebase-storage


【解决方案1】:

我设法解决了。 如果有人需要,这里是工作函数 share():

private fun share(){
    val imageUri = mCamera.imageUri
    if (imageUri != null){
        val uid = mFirebase.auth.currentUser!!.uid
        val uTask = mFirebase.storage.child("users").child(uid).child("images").child(imageUri.lastPathSegment!!).putFile(imageUri)
        mFirebase.storage.child("users").child(uid).child("images").child(imageUri.lastPathSegment!!).putFile(imageUri)
            .addOnCompleteListener {
                if (it.isSuccessful) {
                    uTask.continueWithTask { _ ->
                        mFirebase.storage.child("users").child(uid).child("images")
                            .child(imageUri.lastPathSegment!!).downloadUrl
                    }.addOnCompleteListener {
                        if (it.isSuccessful && it.result != null)
                            mFirebase.database.child("images").child(uid).push()
                                .setValue(it.result.toString())
                                .addOnCompleteListener {
                                    if (it.isSuccessful) {
                                        startActivity(
                                            Intent(
                                                this,
                                                ProfileActivity::class.java
                                            )
                                        )
                                        finish()
                                    } else {
                                        showToast(it.exception!!.message!!)
                                    }
                                }
                    }
                } else {
                    showToast(it.exception!!.message!!)
                }
            }
    }
}

【讨论】:

    【解决方案2】:

    您没有正确使用来自putFile(imageUri) 的结果。你有:

    putFile(imageUri).addOnCompleteListener {
        if (it.isSuccessful){
            mFirebase.database.child("images").child(uid).push()
                .setValue(it.toString())
    

    it.toString() 不是 URL。 itputFile() 返回的 UploadTask 对象。你不能只是把它变成一个字符串——这是一个你需要观察才能得到结果的任务。

    您似乎在 uploadUserPhoto 中正确获取了下载 URL,使用 downloadUrl 获取要写入的 URL。你将不得不这样做。

    另请参阅documentationthis question

    【讨论】:

    • 试过了,删除 toString() - 它使应用程序崩溃并给出 com.google.firebase.database.DatabaseException:发现名称冲突的 getter:getResult
    • 到底试过什么?这个答案解释了为什么你现在拥有的东西不起作用。您根本没有获取下载 URL,除了 uploadUserPhoto,您甚至没有调用它。如果您有其他代码无法正常工作,并且它会产生一个全新的错误,我认为这应该出现在一个新问题中。
    • 我是编程新手,所以不能只按照您提供给我的文档进行操作。我删除了 toString() 只留下“它”,在我点击分享照片后,它使应用程序崩溃。另外,我刚刚写了“updateUserPhoto”,希望有人能告诉我如何修复我的私人乐趣分享()就像“updateUserPhoto”被修复一样
    • 这不是我推荐的解决方案。您需要使用 downloadUrl 从引用中获取下载 URL,其方式与您在 uploadUserPhoto 和我提供的两个链接中使用的方式相同。
    • 我指出您已经知道如何获取下载 URL - 您是在您在问题中发布的 uploadUserPhoto 中进行的。链接的问题还提供了代码示例。您可以调整这些以适应您的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 2014-04-10
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多