I want to get the Download Url from uploadTask.addOnProgressListener method of Firebase. How can I get the Download Url using following code?
UploadTask uploadTask = storageRef.putBytes(data);
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>()
{
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot)
{
Log.d("aaaaasessin",""+taskSnapshot.getTask().getResult());
}
});
I used taskSnapshot.getTask().getResult() but that is not working.
Edit Aug 22th 2019:
There is a new method recently added to StorageReference's class in the Android SDK named list().
To solve this, you need to loop over the ListResult and call getDownloadUrl() to get the download URLs of each file. Remember that getDownloadUrl() method is asynchronous, so it returns a Task object. See below for details. I have even written an article regarding this topic called:
How to upload an image to Cloud Storage and save the URL in Firestore?
In order to get the download url, you need to use addOnSuccessListener, like in the following lines of code:
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String url = uri.toString();
//Do what you need to do with url
}
});
}
});
As in the Firebase release notes on May 23, 2018 is mentioned that:
Cloud Storage version 16.0.1
Removed the deprecated StorageMetadata.getDownloadUrl() and UploadTask.TaskSnapshot.getDownloadUrl() methods. To get a current download URL, use StorageReference.getDownloadUr().
So now when calling getDownloadUrl() on a StorageReference object it returns a Task object and not an Uri object anymore.
Please also rememeber, neither the success listener nor the failure listener (if you intend to use it), will be called if your device cannot reach Firebase Storage backend. The success/failure listeners will only be called once the data is committed to, or rejected by the Firebase servers.
Related
I'm trying to make a social media application with firebase in android studio, now my application is finished, it works smoothly, but there is a problem, there is a delete button on the shared post, when this button is clicked, I want it to delete only that selected picture.
Can you help me, please?
if you're asking about firebase database you can do something like
// Reference to the node you want to delete
DatabaseReference postRef = FirebaseDatabase.getInstance().getReference("posts").child(postId);
// Delete the node
postRef.removeValue();
in case you are talking about firebase storage you can do something like
// Reference to the image you want to delete
StorageReference imageRef = storageRef.child("images/myimage.jpg");
// Delete the image
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted successfully
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
}
});
you must include the dependency in build.gradle
implementation 'com.google.firebase:firebase-storage:19.2.0'
sorry i didn't had enough reputation here to comment and ask so directly posting an answer
my image is stored inside firebase storage and its url is stored inside the realtime database. Firebase realtime and storage are both like this:
Type1
----Time1
--------elements of type1
----Time2
--------elements of type2
Type2
....
I let the users change element's time so I have to move an element from a branch to another.
My strategy is to create a new element on the new branch and then remove the old one.
The problem is in the creation of the new element in the chosen branch, specifically I have problems setting the image of the new element equal to that of the old one.
I tried to use Uri.parse() passing the url saved as string in the realtime database and I also tried to use storagereference.getdownloadurl, both I got this error:
could not locate file for uploading:https://firebasestorage.googleapis.com/v0/b/re...
E/StorageException: StorageException has occurred.
An unknown error occurred, please check the HTTP result code and inner exception for server response.
Code: -13000 HttpResult: 0
And it's not sense because If I click that link in the error, it shows me the correct image, so why it can't locate it?!
How can I do it?
storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/General/Test1");
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/Future/Test1");
storageReference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
...
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
});
The error is on this line:
storageReference.putFile(uri)...
You have to download the bytes from firebase like this:
storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/General/Test1");
storageReference.getBytes(1024*1024).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
//here add new element in the server with storageReference.putbytes(bytes)..
}
});
How to attach PDF file to post API with two parameter? I am using Fast android networking library.
I am able to call API but I when user touched button my API called in my API have three parameters like this:
message = "Test"
receiver_Email = "#gmail.com"
File = text.PDF;
Sy API allows only PDF form met with message and email. I am using Fast android networking library. I try to call API but I am not able to do it.
I also looked at some examples but it couldn't help me out.
just call this method from your onCreate this is the easy way to call API with file and parameter I hope it helps you
//method used to call API to send email
enter code here
#RequiresApi(API = Build.VERSION_CODES.LOLLIPOP_MR1)
public void call_Api()
{
final String key = "file";
final File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "/test.pdf");
AndroidNetworking.initialize(this);
AndroidNetworking.upload("your API")
.setPriority(Priority.HIGH)
.addMultipartParameter("message", "test")
.addMultipartParameter("receiverEmail","testrg0017#gmail.com")
.addMultipartFile(key, file)
.setPriority(Priority.HIGH)
.build()
.getAsJSONObject(new JSONObjectRequestListener()
{
#Override
public void onResponse(JSONObject response)
{
Log.d("res ",response.toString());
if(file.exists())
{
Toast.makeText(PdfGeneration.this, "API call successfully",
Toast.LENGTH_SHORT).show();
}
}
#Override
public void onError(ANError anError)
{
anError.printStackTrace();
Log.d("res12 ",anError.toString());
if(!file.exists())
{
Toast.makeText(PdfGeneration.this, "file not available",
Toast.LENGTH_SHORT).show();
}
}
});
}
I am trying to save data to firebase with the following structure
root
--clothing
----clothingImgDownloadUrl
------title
------category
As I understand I need to make a reference to the path in my database where I want to save the new data.
FirebaseApp app = FirebaseApp.getInstance();
assert app != null;
mDatabase = FirebaseDatabase.getInstance(app);
mClothingRef = mDatabase.getReference("clothing");
I want to add new clothing using the clothing reference created above
mClothingRef.child(clothingImgDownloadUrl).setValue(clothing);
However the code above is only ran once the clothing image is uploaded to firebase storage and its download url is returned to the app where it can be used as the unique identifier for the entries in the firebase database. Below is the code to upload the image to firebase storage.
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference(FIREBASE_STORAGE_CLOTHING_REFERENCE);
StorageReference photoRef = storageRef.child(mSelectedImageUri.getLastPathSegment());
photoRef.putFile(mSelectedImageUri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// When the image has successfully uploaded, we get its download URL
Log.d("ADMIN_ACTIVITY", "Called");
Uri downloadUrl = taskSnapshot.getDownloadUrl();
assert downloadUrl != null;
String imageUrl = downloadUrl.toString();
Clothing clothing = new Clothing(imageUrl, title, mCategory);
mClothingRepository.addClothing(clothing);
}
});
When the app is ran and I add a clothing item from the admin part of the app, the image is indeed added to the firebase storage, however the Log call in the last code snippet is not called. Surely if the image is added then the onSuccess listener should be called and then the addClothing method should be ran.
Why is the onSuccess listener not being called and am I saving to the real time database correctly?
You are using the activity-scoped form of addOnSuccessListener(). The documentation notes that:
The listener will be automatically removed during onStop()
The most likely explanation for the listener not being called is that the activity passed as the first argument (this) has completed and its onStop() method called. To confirm that this is the case, remove the this argument and see if the listener is called.
I've implemented Picasso library for loading the images. Image Caching is working perfectly until we kills the application. If application gets killed Picasso loads images again, no caching. This is a well known bug in this library as I've read it in various blogs, somewhere I read that updating the Picasso library resolves this issue, I did the same but it is still remaining. Right now I am using Picasso Version2.5.2. If anybody has a nice experience with Picasso please let me know a few things.
What is the most updated version of the Picasso?
Is this issue still remaining in Picasso in latest version?
is there tricky solution for this?
Which library i need to use for overcoming this problem?
Thanks in advance.
For loading images after killed app, you should follow instructions:
Server should return image with header Cache-Control
i.e. Cache-Control:public, max-age=604800
more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
You should create own picasso instance:
Cache cache = new Cache(context.getCacheDir(), 30000000);
OkHttpClient client = new OkHttpClient.Builder().cache(cache).build();
OkHttp3Downloader downloader = new OkHttp3Downloader(client);
Picasso picasso = new Picasso.Builder(appContext).downloader(downloader).build();
Load image: picasso.load(url).into(imageView);
Explaination:
Picasso doesn't have a disk cache. It delegates to whatever HTTP client you are using for that functionality (relying on HTTP cache semantics for cache control). Because of this, the behavior you seek comes for free
This is how I implemented Picasso to force it to look for cache records first before fetching the images online again..Due note that the library has a 65MB cache limit..read that somewhere in the documentation
Picasso.with(context)
.load(Link)
.placeholder(R.drawable.grad)
.error(R.drawable.grad)
.networkPolicy(NetworkPolicy.OFFLINE)
.fit()
.centerCrop()
.into(image, new Callback() {
#Override
public void onSuccess() {
//successfully loads from CACHE
image.setClickable(true);
..............
}
#Override
public void onError() {
// fetch online because cache is not there
Picasso.with(context)
.load(Link)
.fetch(new Callback() {
#Override
public void onSuccess() {
Picasso.with(context)
.load(Link)
.fit()
.centerCrop()
.into(image, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
//success..
}
#Override
public void onError() {
Toast.makeText(context, "No Image Found. Try again later", Toast.LENGTH_SHORT).show();
image.setClickable(false);
}
});
}
#Override
public void onError() {
//NO IMAGE offline or online
Toast.makeText(context, "No Image Found. Try again later", Toast.LENGTH_SHORT).show();
image.setClickable(false);
}
});
}
});