【问题标题】:How to upload an image to Firebase storage?如何将图像上传到 Firebase 存储?
【发布时间】: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 存储的默认安全规则需要身份验证。您是否已登录用户或更改规则以允许公共访问?
  • 我刚刚更新了我的堆栈跟踪

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


【解决方案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);
    }

有关更多详细信息,请参阅以下示例:

【讨论】:

  • 您不需要上传任务和 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
    猜你喜欢
    • 2017-09-25
    • 2021-02-20
    • 2016-11-08
    • 2020-12-16
    • 1970-01-01
    • 2018-10-24
    相关资源
    最近更新 更多