TextView myUsername=(TextView) findViewById(R.id.user);
myProfile=(ImageView) findViewById(R.id.photo);
Bundle bundleObject=getIntent().getExtras();
myAccount=(Account) bundleObject.getSerializable("account");
myUsername.setText(myAccount.get_username());
StorageReference profile =
FirebaseStorage.getInstance()
.getReference().child("profiles").child(myAccount.getUID()).child("profile");
profile.getDownloadUrl().addOnSuccessListener(Profile.this, new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
myProfile.setImageURI(uri);
}
});
I'm trying to put the image from the Firebase Storage in the ImageView but is not showing and I don't have any error . What I'm doing wrong?
ImageView doesn't load images from the internet itself - and the URL retrieved from Storage is a regular HTTPS one. The setImageURI method is for loading from the local file system.
You can use a library like Glide or Picasso to do the image loading - if you take a look at FirebaseUI, you'll find a helpful integration that includes caching: https://github.com/firebase/FirebaseUI-Android/tree/master/storage
Related
I have recyclerview and in every row I have an image that I load with firebase storage. It seems like the image loading is affecting the scrolling performance of the recyclerView.
I am using glide to load the images that I got from firebase inside onBindViewHolder by calling imageLoadGlide method like this:
//Download image from firebase Storage and set gameImage("ImageView") image.
private void imageLoadGlide(DocumentSnapshot documentSnapshot, final QuestionsHolder questionsHolder) {
//for firebase storage
FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReference();
storageRef.child(documentSnapshot
.get("image").toString())
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//this part is loading image from url library
Glide
.with(context.getApplicationContext()) // pass Context
.load(uri)// pass the image url
.centerCrop() // optional scaletype
.crossFade() //optional - to enable image crossfading
.transform(new CircleTransform(context))//transfoms the imageView onto circle with the custon class CircleTransform
.into(questionsHolder.gameImage); // the ImageView to which the image is to be loaded
//stop the loading bar from spinning
questionsHolder.loadProgress.setVisibility(View.GONE);
}
});
}
The download works fine but it makes the scrolling super slow.
I have no idea why this is happening because I compress the images before uploading them so I don't think that this is a problem of image weight.
The image compress is made like this :
Bitmap bitmap = ((BitmapDrawable) questionImage.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.putBytes(data);
Any ideas on why this is happening and how can I avoid this?
Here is onBindViewHolder for #Vadim Eksler request:
#Override
public void onBindViewHolder(#NonNull final QuestionsHolder holder, final int position) {
holder.gameImage.setImageBitmap(null);
setInfoForViews(holder, result.get(position));
imageLoadGlide(result.get(position), holder);
setOnClicksListners(holder, position);
setRankTextView(position, holder);
if (position == result.size() - 1 && !endOfDocs && next != null) {
loadMoreDocs(position);
}
}
This answer is based on all the comments together.
So as mentioned in the comments what I did wrong is that every time that onBindViewHolder was called I have pulled the image from firebase again and again - this causes poorly recyclerView performance.
What I did to fix it:
I have used flyweight design pattern to load the image only for the first time from firebase and after that simply recycle this image for the next time onBindViewHolder will get called.
First I created a map as a global variable:
private Map<String, Bitmap> flyweight = new HashMap<>();
after that when the image is loaded from the first time I will save it for later when onBindViewHolder will get called again:
Inside onBindViewHolder :
if (flyweight.get(result.get(position).get("image").toString()) == null) {
imageLoadGlide(result.get(position), holder); // load the image
} else {
//recycle the image that i already have
holder.gameImage.setImageBitmap(flyweight.get(result.get(position).get("image").toString()));
}
And the last thing is to add my image to the map that I created after the image is successfully pulled :
flyweight.put(documentSnapshot.get("image").toString(), resource);
This question already has answers here:
How to display image from URL on Android
(10 answers)
Closed 4 years ago.
Heyho,
currently im working on my Firebase Database (android sdk). I managed to upload the image to the storage and save the url in my database (under the user ID).
Now im really out of ideas how to display the image from the database into a imageView.
Probably you already understand that im trying create some type of "profile picture".
Btw. is would be really nice if someone can help me without using Glide. If Glide is needed i will get Glide then instead.
Thank you all for reading my question and helping me!
Database Image
Firstly you can put an image using an url by using:
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
If you use the Firebase storage why don't you just download the file directly from there?
StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
StorageReference riversRef = mStorageRef.child("images/name.jpg");
File localFile = null;
try {
localFile = File.createTempFile("images", "jpg");
} catch(IOException e) {
e.printStackTrace();
}
riversRef.getFile(localFile)
.addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
// Successfully downloaded data to local file
// ...
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle failed download
// ...
}
});
If you do need to use the url then you will need to use an AsyncTask to get the image.
I have link in my Firebase Storage on .gif file
String gifUrl = "https://firebasestorage.googleapis.com/v0/b/rokitskiydev-a18ca.appspot.com/o/WF%2F10-16-02-Digital-15.gif?alt=media&token=0354f6e6-4292-4911-9302-49281d293a80";
I try use Picasso and Glide. But I can show only image of this gif.
GlideApp.with(context).load(gifUrl).into(ImageView);
If i get another link, an example http://i.imgur.com/1ALnB2s.gif it's OK!
How can I do this?
Get the downloadUrl of the gif and then use that to load the gif with Glide.
ImageView imageView = (ImageView) findViewById(R.id.imageView);
GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageView);
Glide.with(this).load(downloadUrl).into(imageViewTarget);
For newer versions of Glide try this:
Glide.with(context)
.load(imageUrl)
.asGif()
.placeholder(R.drawable.loading2)
.crossFade()
.into(imageView);
As Glide Documentation says,
You can use .asGif() to force the library to load an animated gif and fail if it is not :
Glide.with(activity).load(gifUrl).asGif().into(view);
try this
Check the doc: https://futurestud.io/tutorials/glide-displaying-gifs-and-videos
also as FirebaseDoc says you can do this to load an image/gif with glide
first declare this in your build.gradle
dependencies {
// FirebaseUI Storage only
compile 'com.firebaseui:firebase-ui-storage:0.6.0'
}
then
this to load your image with firebase
// Reference to an image file in Firebase Storage
StorageReference storageReference = ...;
// ImageView in your Activity
ImageView imageView = ...;
// Load the image using Glide
Glide.with(this /* context */)
.using(new FirebaseImageLoader())
.load(storageReference)
.into(imageView);
if you need the url of your image/gif file, you can do this
storageRef.child("your/firebase/imagepath.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// Got the download URL for 'users/me/profile.png'
Uri downloadUri = taskSnapshot.getMetadata().getDownloadUrl();
generatedFilePath = downloadUri.toString(); /// The string(file link) that you need
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
I am trying to do the image upload and download for a user profile, when I save a photo I save it with the userId so I can replace it everytime he changes his photo, now what I need is to get that photo with picasso, the thing is, I don't know how to get the photo, it can have different formats and other stuffs like jpeg, png, I just want to get the image when the userID match, I tried this:
storageRef = storage.getReferenceFromUrl("gs://friendlymanager-3b7a2.appspot.com");
Picasso.with(UserSettings.this).load(storageRef + "/Photos/" + userId).into(userImage);
my userImage is my imageView, i don't get any erros just a blank image, i already have a photo for the specific user.
Any help?
you will have to get download link like this,
StorageReference storageRef = storage.getReference().child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child(FirebaseAuth.getInstance().getCurrentUser().getUid());//reach out to your photo file hierarchically as stored on firebase
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Log.e("URI", uri.toString());
Glide.with(SaveUserActivity.this).load(uri).into(profile_image);
url = uri.toString();
}
});
Consider using Firebase-UI Android library which gives you ability to load images from storage ref directly. In your case it would look something like this
I'm not sure if Picasso is supported but you can use Glide
for example:
mStorageRef = FirebaseStorage.getInstance().getReference();
Glide.with(this /* context */)
.using(new FirebaseImageLoader())
.load(mStorageRef + "/Photos/" + userId)
.error(R.drawable.default)
.into(imageView);
You should use getDownloadUrl() while fetching images from Firebase storage using Picasso OR glide etc.
I am adding images for all user in storage section, below is my code for uploading images.
public void uploadImage(byte[] data, final String fileName) {
mProgressDialog.setMessage("Uploading image....");
mProgressDialog.show();
StorageReference filepath=mStorageRef.child("Photos").child(fileName);
filepath.putBytes(data).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mProgressDialog.dismiss();
String mUrl=taskSnapshot.getDownloadUrl().toString();
// got url for this image what to do with this url.....
Toast.makeText(MainActivity1.this,"Upload done!",Toast.LENGTH_LONG).show();
}
});
}
I want to obtain all images url stored for a particular user.
There is no API for listing items of Firebase Storage on the client side.
You should modify your file upload method to also store that download URL somewhere in the user's control, like a user-specific path in the Realtime Database.