Firebase Auth:我想获取当前用户个人资料照片并将其上传到 Firebase 数据库或存储

Posted

技术标签:

【中文标题】Firebase Auth:我想获取当前用户个人资料照片并将其上传到 Firebase 数据库或存储【英文标题】:Firebase Auth: I want to get the current user profile photo and upload it to firebase database or storage 【发布时间】:2021-09-20 06:29:38 【问题描述】:

我想在我的聊天应用程序的图像视图支架中显示个人资料图片。我已经实现了 google 和 facebook 等 firebase auth 登录方法。所以我想在他们聊天时显示用户图像。我可以通过FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl(); 显示当前用户图像但是当我想获取另一个用户的图像时?所以我尝试了以下方法,

注册应用后,我可以获取他们的个人资料图片并将其上传到 Firebase 存储。之后我可以在应用程序的聊天头中使用它。所以下面是代码

Uri dpUri = currentFirebaseUser.getPhotoUrl();
if (dpUri != null) 
    final ProgressDialog progressDialog = new ProgressDialog(this);
    progressDialog.setTitle("Uploading...");
    progressDialog.show();

    final StorageReference ref = storageReference.child(currentFirebaseUser.getUid());
    ref.putFile(dpUri)
            .addOnSuccessListener(taskSnapshot -> 
                ref.getDownloadUrl().addOnSuccessListener(uri -> databaseReference.child("Users").child(currentFirebaseUser.getUid()).child("URL").setValue(uri.toString()));

                progressDialog.dismiss();

                LocationOn();
            )
            .addOnFailureListener(e -> 
                progressDialog.dismiss();
                Toast.makeText(SignActivity.this, "Failed " + e.getMessage(), Toast.LENGTH_SHORT).show();
            )
            .addOnProgressListener(taskSnapshot -> 
                double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot
                        .getTotalByteCount());
                progressDialog.setMessage("Uploaded " + (int) progress + "%");
            );

但不可读,我收到此错误:

E/UploadTask: could not locate file for uploading:https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
E/StorageException: StorageException has occurred.
    An unknown error occurred, please check the HTTP result code and inner exception for server response.
     Code: -13000 HttpResult: 0
E/StorageException: No content provider: https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
    java.io.FileNotFoundException: No content provider: https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1979)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1808)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1485)
        at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:131)
        at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:240)
        at com.myapp.SignActivity.uploadImage(SignActivity.java:143)
        at com.axresapps.wheresapplk.SignActivity.lambda$onCreate$2$SignActivity(SignActivity.java:123)
        at com.myapp.-$$Lambda$SignActivity$__O5f7J8hhcqZRFrdV0j4-3CaQk.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
E/StorageException: StorageException has occurred.
    An unknown error occurred, please check the HTTP result code and inner exception for server response.
     Code: -13000 HttpResult: 0
E/StorageException: No content provider: https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
    java.io.FileNotFoundException: No content provider: https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1979)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1808)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1485)
        at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:131)
        at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:240)
        at com.axresapps.wheresapplk.SignActivity.uploadImage(SignActivity.java:143)
        at com.myapp.SignActivity.lambda$onCreate$2$SignActivity(SignActivity.java:123)
        at com.axresapps.wheresapplk.-$$Lambda$SignActivity$__O5f7J8hhcqZRFrdV0j4-3CaQk.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
E/StorageException: StorageException has occurred.
    An unknown error occurred, please check the HTTP result code and inner exception for server response.
     Code: -13000 HttpResult: 0
E/StorageException: No content provider: https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
    java.io.FileNotFoundException: No content provider: https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1979)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1808)
        at android.content.ContentResolver.openInputStream(ContentResolver.java:1485)
        at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:131)
        at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:240)
        at com.axresapps.wheresapplk.SignActivity.uploadImage(SignActivity.java:143)
        at com.axresapps.wheresapplk.SignActivity.lambda$onCreate$2$SignActivity(SignActivity.java:123)
        at com.axresapps.wheresapplk.-$$Lambda$SignActivity$__O5f7J8hhcqZRFrdV0j4-3CaQk.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

请帮我修复它或建议我另一种方法来完成我的任务

【问题讨论】:

您应该编辑您的问题,不要提及“Firebase 存储”,因为您实际上只是将用户的配置文件 URL 存储到您的“Firebase 实时数据库”中。 【参考方案1】:

您可以通过以下三种方式之一将文件上传到 Firebase 存储:1) 本地文件,2) 字节数组,3) base64 编码的数据字符串。您正在使用图像的 URL 调用 putFile,这是不受支持的。

您将不得不采用两步法:

    将数据从 URL 下载到 Android 设备, 然后将数据从 Android 设备上传到 Storage。

另见:

Upload image from URL to Firebase Storage

【讨论】:

【参考方案2】:

我建议您在将个人资料图片上传到 FirebaseStorage 之前执行此操作。

    获取在ImageView 上显示的图片网址。 将图像转换为字节。
    val bitmap = (binding.ivPicture.drawable as BitmapDrawable).bitmap
    val baos = ByteArrayOutputStream()
    bitmap.compress(
        Bitmap.CompressFormat.JPEG,
        30,
        baos
    )
    val data = baos.toByteArray()
    // Create file metadata including the content type
    val metadata = storageMetadata 
        contentType = "image/jpeg"
    
    将字节存储到 FirebaseStorage
    val uploadTask = storage.putBytes(data, metadata)
    uploadTask.addOnFailureListener 
        // Handle unsuccessful uploads
        Tools.showToast(
            this,
            "Error uploading image: " + it.message
        )
         
    .addOnSuccessListener 
        storage.downloadUrl.addOnCompleteListener  task ->
            if (task.isSuccessful) 
                //Get download url to store in the database.
                val profileUrl = task.result.toString()
    
             else 
    
                Tools.showToast(
                    this,
                    "Error saving: " + task.exception?.message
                )
    
            
        
    

【讨论】:

但是我需要获取firebase auth 图像,我已经知道如何将图像上传到firebase 商店! @LakpriyaSenevirathna 你误解了这段代码的作用,你将图像从user.getPhotoUrl() 加载到ImageView,然后在第 2 步中,它将缓存的图像存储在视图中并转换它到一个字节数组,然后在第 3 步中将其上传到 Cloud Storage 是的。你的方法也是正确的。在下面访问我的答案!我认为这是最好的方法!【参考方案3】:

终于找到了解决办法。我做了这样的事情!

 if(currentFirebaseUser.getPhotoUrl()!=null)
     databaseReference.child("Users").child(currentFirebaseUser.getUid()).child("URL").setValue(currentFirebaseUser.getPhotoUrl().toString());
 

您将在 firebase 数据库中看到图片网址

如果您使用 Google OAuth;

https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1=s96-c

如果您删除 =s96-c ,您可以获得高质量的图像!

https://lh3.googleusercontent.com/a/AATXAJzFGstrkeyXMQUU9XIKEXIL8jgEgm1T-EKi3AW1

如果您使用任何其他 Oauth 方法。它工作正常,我尝试了 yahoo Oauth,它将通过currentFirebaseUser.getPhotoUrl().toString() 检索个人资料图片的网址

【讨论】:

重要的是,用户的photoURL 并不总是托管在googleusercontent.com 上,您可能会根据他们的身份验证方式获得Facebook、Twitter 等存储的图像。 @samthecodingman 它也适用于其他 oauth 构建者!我试过雅虎!

以上是关于Firebase Auth:我想获取当前用户个人资料照片并将其上传到 Firebase 数据库或存储的主要内容,如果未能解决你的问题,请参考以下文章

从当前用户 firebase swift 获取文档

我想检索用户生成的数据,但在Firebase中获取权限被拒绝错误

Firebase 规则如何获取“request.auth.uid”字段?

如何在 Flutter 中从 Firebase Auth 获取用户 ID?

如何从 firebase_auth 获取令牌

Firebase 的云功能 - 获取当前用户 ID [重复]