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(); } }); } }
额外注意事项
- 图片质量优化:如果觉得当前缩略图尺寸太小,可以修改相机Intent逻辑,指定本地文件路径保存原图,上传高质量图片,需要的话我可以补充这部分代码。
- 权限配置:确保你的
AndroidManifest.xml中添加了必要权限:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.INTERNET" />
- 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
相关产品推荐
相关产品推荐

