Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picasso can't load image inside StorageReference's onSuccess method

When trying Picasso on the runtime onStart() method it normally loads the image from Firebase using the download link from the console.

But when I try to load an image inside StorageReference onSuccess method it just won't work.

This class is extending Fragment:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == GALLERY_IN && resultCode == Activity.RESULT_OK) {
        isGranted = true;
        String path = FireStorage.retUID() + "/";
        showIndProgress();
        Uri uri = data.getData();

        StorageReference childPathRef = FireStorage.storageRef.child(path + uri.getLastPathSegment());
        childPathRef.putFile(uri)
                .addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                        if(task.isSuccessful()) {
                            Picasso.with(mContext).load(task.getResult().getDownloadUrl())
                                    .into(profView);

                            Picasso.Builder build = new Picasso.Builder(mContext);
                            build.listener(new Picasso.Listener() {
                                @Override
                                public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
                                    Toast.makeText(mContext, "exception\n" + exception.toString(), Toast.LENGTH_SHORT).show();

                                }
                            });
                            progressDialog.dismiss();
                        } else {
                            //failed
                        }

                    }
                });

    }

}

This is my FirebaseStorage instance on another Class:

public static FirebaseStorage storage = FirebaseStorage.getInstance();
public static StorageReference storageRef = 
                           storage.getReferenceFromUrl("gs://myurl.appspot.com/");

Manifest:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

My XML layout:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="@drawable/gcover"
    android:id="@+id/relativeLayout">

    <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/profPhoto"
        android:clickable="true"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:padding="20dp"
        android:src="@drawable/default_prof"
        android:scaleType="centerCrop"
        app:civ_border_color="@color/trans"
        app:civ_border_width="2dp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

My views initialization:

@Override
public View onCreateView(LayoutInflater inflater,
                         ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_prof, container, false);
    profView = (CircleImageView) view.findViewById(R.id.profPhoto);

    btn1 = (Button) view.findViewById(R.id.btn_1);
    btn2 = (Button) view.findViewById(R.id.btn_2);
    btn3 = (Button) view.findViewById(R.id.btn_3);
    return view;
}
like image 372
GGWP Avatar asked Jun 17 '17 12:06

GGWP


1 Answers

Update 2:

While the code I posted works for me, you indicate that it fails for you. My test does not use a fragment, I don't know what version of the libraries you are using, it's now known how the fragment is being added to the layout, etc. There are too many possible causes of the different behavior to effectively debug it on SO.

As an experiment, you can try using Glide and FirebaseUI to perform the download instead of Picasso. The code is shown below and works for me. Because the download is from the storage reference and not the URL, this approach requires read access to the storage. You also need to add these lines to your build dependencies:

// FirebaseUI 2.0.1 is the version to use for Firebase SDK version 11.0.1
// SDK/Firebase version compatibility is important.
// See the FirebaseUI docs for a table of compatible versions.
compile 'com.firebaseui:firebase-ui-storage:2.0.1'
compile 'com.github.bumptech.glide:glide:3.8.0'

.

childPathRef.putFile(Uri.fromFile(file))
    .addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
            if (task.isSuccessful()) {
                Log.d(TAG, "Upload: SUCCESS");

                Glide.with(mContext)
                    .using(new FirebaseImageLoader())
                    .load(childPathRef)
                    .dontAnimate()
                    .listener(new RequestListener<StorageReference, GlideDrawable>() {
                        @Override
                        public boolean onException(Exception e, StorageReference model,
                               Target<GlideDrawable> target, boolean isFirstResource) {
                            Log.e(TAG, "Download: FAILED: ", e);
                            return false;
                        }
                        @Override
                        public boolean onResourceReady(GlideDrawable resource,
                               StorageReference model, Target<GlideDrawable> target,
                               boolean isFromMemoryCache, boolean isFirstResource) {
                            Log.d(TAG, "Download: SUCCESS");
                            return false;
                        }
                    })
                    .into(mCircleImageView);
            } else {
                Log.e(TAG, "Upload: FAILED: " + task.getException().getMessage());
            }
        }
    });

Update:

Additional debugging showed that the upload and download were both completing sucessfully. The problem was with the rendering of the downloaded image. The documentation for CircleImageView indicates that noFade() must be used when downloading from Picasso:

If you use an image loading library like Picasso or Glide, you need to disable their fade animations to avoid messed up images. For Picasso use the noFade() option, for Glide use dontAnimate().

It was also found that small images were rendered but large images were displayed as black. fit() was added to cause Picasso to resize the image.


To detect both upload success and failure, use a completion listener instead of just a success listener, and test task.isSuccessful(). The upload is probably failing because of security rules, or invalid StorageReference:

StorageReference childPathRef = Class.storageRef.child(path + uri.getLastPathSegment());
childPathRef.putFile(uri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
        if (task.isSuccessful()) {
            Log.d(TAG, "Upload: SUCCESS");
            Picasso.with(mContext)
                .load(task.getResult().getDownloadUrl())
                .noFade()
                .fit()
                .into(profView, new Callback() {
                    @Override
                    public void onSuccess() {
                        Log.d(TAG, "Download: SUCCESS");
                        Toast.makeText(mContext, "download done" , Toast.LENGTH_SHORT).show();                        }

                    @Override
                    public void onError() {
                        Log.d(TAG, "Download: FAILED");
                    }
                });
            Toast.makeText(mContext, "upload done" , Toast.LENGTH_SHORT).show();
        } else {
            Log.e(TAG, "Upload: FAILED: " + task.getException().getMessage());
        }
        progressDialog.dismiss();
    }
});
like image 105
Bob Snyder Avatar answered Oct 24 '22 18:10

Bob Snyder