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;
}
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 usedontAnimate()
.
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();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With