0

I'm trying to upload an image to Firebase Storage and after that send the URL of this image to Firebase Database. The Uri is correct, but when I try to set it on my object, the method singleDetection.setImage(imagePath) is setting nothing. Here is my code:

Bitmap image = detectedFaceItems.get(0).getImage();
        StorageReference storageRef = storage.getReference();
        StorageReference imagesRef = storageRef.child("2.jpg");

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] data = baos.toByteArray();
        StorageTask<UploadTask.TaskSnapshot> uploadTask = imagesRef.putBytes(data)
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(getApplicationContext(), "Failed to sent a file", Toast.LENGTH_LONG).show();
                    }
                })
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        Toast.makeText(getApplicationContext(), "Successfully sent a file", Toast.LENGTH_LONG).show();
                        storageRef.child("2.jpg").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                            @Override
                            public void onSuccess(Uri uri) {
                                //Toast.makeText(getApplicationContext(), uri.toString(), Toast.LENGTH_LONG).show();
                                //Doesn't work corretly
                                String imagePath = uri.toString();
                                singleDetection.setImage(imagePath);
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Toast.makeText(getApplicationContext(), "Failed to get an Uri", Toast.LENGTH_LONG).show();
                            }
                        });
                    }
                });
AndroideuszPL
  • 385
  • 1
  • 2
  • 13
  • I'm not sure what `singleDetection.setImage(imagePath)` is supposed to do. But if you `Log.i("URL", imagePath)`, what does that output in your logcat? – Frank van Puffelen May 04 '20 at 23:43
  • setImage just set string to object. Log.i("URL", imagePath) and Log.i("URL", singleDetection.getImage()) inside the onSuccess method return url correctly, but Log.i("URL", singleDetection.getImae()) outside the onSuccess method returns nullPointerException. – AndroideuszPL May 05 '20 at 09:14
  • That is expected: since the download URL is retrieved from the server, any code that needs to access the download URL needs to be inside `onSuccess` or be called from there. See https://stackoverflow.com/questions/53127996/getdownloadurl-isnt-inputting-the-link-i-need/53128190#53128190 – Frank van Puffelen May 05 '20 at 13:04

1 Answers1

0

You are uploading the image right, but your call to Firebase after successfully uploading the image using storageRef.child("2.jpg").getDownloadUrl(). not that right as you already don't know the generated Uri which you can get from the snapshot that is returned back with the taskSnapshot.

So replace the below part of code:

.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
        Toast.makeText(getApplicationContext(), "Successfully sent a file", Toast.LENGTH_LONG).show();
        storageRef.child("2.jpg").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                //Toast.makeText(getApplicationContext(), uri.toString(), Toast.LENGTH_LONG).show();
                //Doesn't work corretly
                String imagePath = uri.toString();
                singleDetection.setImage(imagePath);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(getApplicationContext(), "Failed to get an Uri", Toast.LENGTH_LONG).show();
            }
        });
    }
});

With:

 .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

        // get upload url
        taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
            @Override
            public void onComplete(@NonNull Task<Uri> task) {
                String imagePath = String.valueOf(task.getResult());
                singleDetection.setImage(imagePath);

            }
        });
    }
});

Note: here you've uploaded the image itself, but don't upload its Uri, so you can to decide to upload it to firebase as you'd like.

Zain
  • 37,492
  • 7
  • 60
  • 84