如何将图像上传到 Firebase 存储?
Posted
技术标签:
【中文标题】如何将图像上传到 Firebase 存储?【英文标题】:How to upload an image to Firebase storage? 【发布时间】:2017-03-27 16:30:51 【问题描述】:我正在尝试将一个简单的字节数组上传到 Firebase 存储中,但我的 onFailureListener
不断被调用并返回给我说上传失败。我希望你们能告诉我我的代码有什么问题。
在顶部我得到了
//Firebase
private Firebase mRef;
private StorageReference storageRef;
然后在onStart()
@Override
protected void onStart()
super.onStart();
googleApiClient.connect();
//Firebase
mRef = new Firebase("link to firebase account");
FirebaseStorage storage = FirebaseStorage.getInstance();
storageRef = storage.getReferenceFromUrl("link to storage");
然后在我的onActivityResult()
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
addImageImageView.setVisibility(View.GONE);
if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null)
//First we gotta make sure to add the images to
ArrayList<Image> imagesFromGallery = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
for (int i = 0; i < imagesFromGallery.size(); i++)
try
//try uploading it
InputStream stream = new FileInputStream(new File(imagesFromGallery.get(i).path));
StorageReference imageStorage = storageRef.child("cardImages/" + "testImages");
UploadTask uploadTask = imageStorage.putStream(stream);
uploadTask.addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
Log.d("myStorage","failure :(");
).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
Log.d("myStorage","success!");
);
catch (UnsupportedEncodingException e)
e.printStackTrace();
catch (FileNotFoundException e)
e.printStackTrace();
这是我的堆栈跟踪:
11-13 21:27:00.392 31388-996/com.daprlabs.aaron.swipedeck2 E/StorageException: StorageException has occurred.
User does not have permission to access this object.
Code: -13021 HttpResult: 403
11-13 21:27:00.392 31388-996/com.daprlabs.aaron.swipedeck2 E/StorageException: The server has terminated the upload session
java.io.IOException: The server has terminated the upload session
at com.google.firebase.storage.UploadTask.az(Unknown Source)
at com.google.firebase.storage.UploadTask.ay(Unknown Source)
at com.google.firebase.storage.UploadTask.run(Unknown Source)
at com.google.firebase.storage.StorageTask$5.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
11-13 21:27:00.406 31388-31388/com.daprlabs.aaron.swipedeck2 D/myStorage: failure :(
【问题讨论】:
在onFailure()
中,将e.getMessage()
添加到日志消息中,查看异常原因。
您是否已授予 INTERNET 权限?
documentation 解释说 Firebase 存储的默认安全规则需要身份验证。您是否已登录用户或更改规则以允许公共访问?
我刚刚更新了我的堆栈跟踪
【参考方案1】:
您需要登录用户或更改安全规则以允许公共访问。这在Firebase Storage Security 的文档中进行了解释。
对于初始开发,您可以在 Firebase 控制台更改规则以允许公共访问:
service firebase.storage
match /b/project-XXXXXXXXXXXXXX.appspot.com/o
match /allPaths=**
// Provide access to all users
allow read: if true;
allow write: if true;
【讨论】:
您写道:“...匹配 /b/project-XXXXXXXXXXXXXX.appspot.com/o ...”。我必须输入项目包名称或项目所谓的面向公众的名称。我的是项目-xxxxxxxx? @CodeToLife:自从我写下这个答案后,情况似乎发生了变化。最初,使用的是项目 ID(显示在项目设置的常规选项卡上)。现在看起来你可以使用bucket
。有关示例,请参见 sample rules。【参考方案2】:
我使用此代码上传图片:
private void uploadFile(Bitmap bitmap)
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("Your url for storage");
StorageReference mountainImagesRef = storageRef.child("images/" + chat_id + Utils.getCurrentTimeStamp() + ".jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception exception)
// Handle unsuccessful uploads
).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
Uri downloadUrl = taskSnapshot.getDownloadUrl();
sendMsg("" + downloadUrl, 2);
Log.d("downloadUrl-->", "" + downloadUrl);
);
依赖:
项目级别等级:classpath 'com.google.gms:google-services:3.0.0'
应用级等级:compile 'com.google.firebase:firebase-storage:9.0.2'
【讨论】:
你知道我们是否需要在 app gradle 中包含任何用于 firebase 存储的内容吗? 在项目级gradel中,我们需要类路径'com.google.gms:google-services:3.0.0'和应用级gradel,我们需要编译'com.google.firebase:firebase-storage :9.0.2' 定义【参考方案3】:只需调用此方法即可将您的图像存储到 Firebase。
private void storeImageToFirebase()
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8; // shrink it down otherwise we will use stupid amounts of memory
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoUri.getPath(), options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] bytes = baos.toByteArray();
String base64Image = Base64.encodeToString(bytes, Base64.DEFAULT);
//For the API less than 28 (android version 8 )
//String base64Image = android.util.Base64.encodeToString(bytes, android.util.Base64.DEFAULT);
// we finally have our base64 string version of the image, save it.
firebase.child("pic").setValue(base64Image);
System.out.println("Stored image with length: " + bytes.length);
有关更多详细信息,请参阅以下示例:
Sample 1 Sample 2【讨论】:
您不需要上传任务和 StorageReference 来将其放入 firebase 存储吗? 我想将图像放入存储而不是 firebase 数据库 您的第一个链接现在不再可用。【参考方案4】:这个方法对我很有效:
private void uploadImage(Bitmap bitmap)
progressDialog.show();
final StorageReference ref = storageReference.child("drivers/" + UserDto.getId() + ".jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
byte[] data = baos.toByteArray();
final UploadTask uploadTask = ref.putBytes(data);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
progressDialog.dismiss();
Toast.makeText(ProfileActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>()
@Override
public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception
if (!task.isSuccessful())
throw task.getException();
return ref.getDownloadUrl();
).addOnCompleteListener(new OnCompleteListener<Uri>()
@Override
public void onComplete(@NonNull Task<Uri> task)
if (task.isSuccessful())
Uri downUri = task.getResult();
Log.d("Final URL", "onComplete: Url: " + downUri.toString());
);
).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
progressDialog.dismiss();
Toast.makeText(ProfileActivity.this, "Failed " + e.getMessage(), Toast.LENGTH_SHORT).show();
);
【讨论】:
【参考方案5】:将多个图像上传到 Firebase 存储。
它对我有用。
使用这个库
compile 'com.github.darsh2:MultipleImageSelect:3474549'
在顶部
private StorageReference storageRef;
private FirebaseApp app;
private FirebaseStorage storage;
onCreate()
app = FirebaseApp.getInstance();
storage =FirebaseStorage.getInstance(app);
按钮点击动作
Gallary.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent intent = new Intent(ChatActivity.this, AlbumSelectActivity.class);
intent.putExtra(Constants.INTENT_EXTRA_LIMIT, 10);
startActivityForResult(intent, Constants.REQUEST_CODE);
);
活动结果
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK)
ArrayList<Image> images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
Uri[] uri=new Uri[images.size()];
for (int i =0 ; i < images.size(); i++)
uri[i] = Uri.parse("file://"+images.get(i).path);
StorageReference ref = storage.getReference("photos").child(uri[i].getLastPathSegment());
ref.putFile(uri[i])
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
Uri downloadUrl = taskSnapshot.getDownloadUrl();
String content = downloadUrl.toString();
)
.addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception exception)
)
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>()
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot)
//displaying the upload progress
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
progressDialog.setMessage("Uploaded " + ((int) progress) + "%...");
);
【讨论】:
你能分享这个的github链接吗? @Nizamudeen Sherif 我将发送到源代码。请提供您的邮件ID以上是关于如何将图像上传到 Firebase 存储?的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Firebase Firestore 中存储下载 URL
如何将图像上传到firebase存储然后将图像url存储在firestore中?