You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android带认证将相机拍摄图片上传至Firebase的实现方案

解决Firebase认证结合相机图片上传的问题

我来帮你搞定这个需求!你已经完成了相机拍照和图片显示的核心功能,接下来只需要调整代码,就能把拍摄的图片上传到Firebase Storage,同时把图片的下载链接关联到当前登录用户的数据库记录里。下面是具体的修改步骤和完整代码:

关键修改点说明

  • 新增全局变量保存拍摄的Bitmap对象(因为ACTION_IMAGE_CAPTURE返回的是缩略图Bitmap,而非Uri),方便后续上传操作
  • 完善saveUserInformation方法,实现Bitmap转字节流、上传到Storage、获取下载链接并更新数据库的完整流程
  • 添加上传/数据库操作的成功/失败回调提示,方便调试和给用户反馈

修改后的完整代码

package com.example.android.besafe;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.firebase.auth.FirebaseAuth;
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 java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;

public class CameraActivity extends AppCompatActivity {
    private ImageButton mProfileImage;
    private ImageView imageview;
    private FirebaseAuth mAuth;
    private DatabaseReference mCustomerDatabase;
    private String userID;
    private Button confirm;
    private static final int CAMERA_REQUEST_CODE = 1;
    // 新增全局变量保存拍摄的Bitmap
    private Bitmap capturedBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        mProfileImage = findViewById(R.id.btnselect);
        confirm = findViewById(R.id.btnsubmit);
        imageview = findViewById(R.id.imageview);

        mAuth = FirebaseAuth.getInstance();
        // 增加登录状态判断,避免未登录时的空指针问题
        if (mAuth.getCurrentUser() == null) {
            Toast.makeText(this, "请先完成登录", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        userID = mAuth.getCurrentUser().getUid();
        mCustomerDatabase = FirebaseDatabase.getInstance().getReference()
                .child("Users").child("fbusersinfo").child(userID);

        mProfileImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent,CAMERA_REQUEST_CODE);
            }
        });

        confirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (capturedBitmap != null) {
                    saveUserInformation();
                } else {
                    Toast.makeText(CameraActivity.this, "请先拍摄照片", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK){
            // 获取拍摄的Bitmap并保存到全局变量
            capturedBitmap = (Bitmap)data.getExtras().get("data");
            imageview.setImageBitmap(capturedBitmap);
        }
    }

    private void saveUserInformation() {
        // 创建Storage引用,用用户ID作为文件名,避免重复冲突
        StorageReference filePath = FirebaseStorage.getInstance().getReference()
                .child("profile_images").child(userID + ".jpg");

        // 将Bitmap转成字节数组,可调整压缩质量(0-100),数值越高质量越好
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        capturedBitmap.compress(Bitmap.CompressFormat.JPEG, 70, baos);
        byte[] imageData = baos.toByteArray();

        // 执行上传操作
        UploadTask uploadTask = filePath.putBytes(imageData);
        uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                // 获取图片的永久下载链接
                taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri downloadUrl) {
                        // 更新数据库中当前用户的头像链接
                        Map<String, Object> newImage = new HashMap<>();
                        newImage.put("profileImageUrl", downloadUrl.toString());
                        mCustomerDatabase.updateChildren(newImage)
                                .addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void aVoid) {
                                        Toast.makeText(CameraActivity.this, "图片上传成功", Toast.LENGTH_SHORT).show();
                                        finish();
                                    }
                                })
                                .addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(Exception e) {
                                        Toast.makeText(CameraActivity.this, "数据库更新失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
                                    }
                                });
                    }
                });
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                Toast.makeText(CameraActivity.this, "图片上传失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

额外注意事项

  1. 图片质量优化:如果觉得当前缩略图尺寸太小,可以修改相机Intent逻辑,指定本地文件路径保存原图,上传高质量图片,需要的话我可以补充这部分代码。
  2. 权限配置:确保你的AndroidManifest.xml中添加了必要权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
  1. Firebase规则设置:在Firebase控制台给Storage设置合适的访问规则,比如允许已登录用户上传:
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /profile_images/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

内容的提问来源于stack exchange,提问作者Ahmed Abbas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:30:16