getDownloadUrl Firebase Storage returns Null (Android) - android

I am developing a little project and i have some issues about firebase Storage and getDownloadUrl.
I have some images already uploaded on FirebaseStorage but when I try to get the download Url it return nulls.
Here is the code:
Imports:
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
Function getImage()
public void getImage(){
StorageReference myStorage = FirebaseStorage.getInstance().getReference();
StorageReference newStorage = myStorage.child("picture").child("pic_one.jpg");
newStorage.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
myuri = uri;
}
});
}
The rules on Firebase Storage without any authentication
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
When the app runs the line getDownloadUrl doesn't do anything, I mean I want to retrieve the https link to show the picture in another activity using glide, but I just get null on myuri variable.
The variable myuri is defined as URI.
Thanks in advance.

Try to do this:
private String generatedFilePath;
myStorage.child("picture").child("pic_one.jpg").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// Got the download URL for 'pic_one.jpg'
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
}
});
Also, it is not possible to get the downloadURL from the root of the storage tree. You should store the downloadURL of the file programmatically to your database in order to access it later on, so first upload the photo to your storage and then in the onSuccess you should upload the downloadURL to your database, then retrieve it from there.
In order to do this you should first declare your databaseReference
private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();
and then, after you upload succefully your picture to the storage, grab the downloadURL and post it to your database
this is an example from the official doc
Uri file = Uri.fromFile(new File("path/to/images/rivers.jpg"));
StorageReference riversRef = storageRef.child("images/"+file.getLastPathSegment());
uploadTask = riversRef.putFile(file);
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
Uri downloadUrl = taskSnapshot.getDownloadUrl(); //After uploading your picture you can get the download url of it
mDatabase.child("images").setValue(downloadUrl); //and then you save it in your database
}
});
and then just remember to get the downloadURL from the database like this:
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String downloadURL = dataSnapshot.getValue(String.class);
//do whatever you want with the download url
}

Related

Getting permission error on Firebase storage in Android?

So I upload a file to firebase storage using this code snippet:
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference parentReference = storage.getReference();
Uri file = Uri.fromFile(new File(PATH));
StorageReference childReference = parentReference.child("kas_data");
UploadTask uploadTask = childReference.putFile(file);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
//
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//
}
});
The upload takes place successfully. Checking the firebase console I see the file is uploaded successfully. Now I want to download it using the following code snippet:
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference parentReference = storage.getReference();
StorageReference childReference = parentReference.child("kas_data");
File localFile = new File(PATH);
childReference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
//
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
//
}
});
But I get the following error message:
com.google.firebase.storage.StorageException: User does not have permission to access this object.
While I'm using this rule at Firebase Storage Rules section:
rules_version = '2';
service firebase.storage {
match /{allPaths=**} {
allow read, write;
}
}
How can I solve the issue?
You can just use Glide to download images just add:
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
To your app build.gradle then
StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
final StorageReference imgRef = mStorageRef.child("Imagesfolder/"+"Imagename"+"");
GlideApp.with(showProducts.this)
.load(imgRef)
.into(imageview);
This will download the image into an imageview!
I'm really not even sure how your upload task succeeded. You need to add a condition to the rules:
match /{allPaths=**} {
allow read, write: if true;
//Or whatever condition you want to allow/disallow uploading and downloading
}

Android Firebase uploading images wrong URL (PROBLEM: X-Goog-Upload-Comment header is missing)

I'm trying to upload and download images from Firabase Database which has an URL link to Firebase Storage. The problem is that the strange URL is being saved to database (see the link at the bottom). What should I do to obtain a normal URL that I will be able to use do downloand the image into my Android app? Thank you in advance!
Here I post some code I use:
Upload to Firebase DataBase and Storage:
mStorageRef = FirebaseStorage.getInstance().getReference();
mDataBaseRef = FirebaseDatabase.getInstance().getReference();
if (mImageUri != null)
{
final StorageReference fileReference = mStorageRef.child(nameimage + "." + getFileExtension(mImageUri));
fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(AddAdvertisement.this, "Upload successful!", Toast.LENGTH_LONG).show();
Upload upload = new Upload(et_localization, taskSnapshot.getUploadSessionUri().toString());
String uploadId = mDataBaseRef.push().getKey();
mDataBaseRef.child(uploadId).setValue(upload);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(AddAdvertisement.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
And download from Firebase:
databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren())
{
Upload upload = postSnapshot.getValue(Upload.class);
mUploads.add(upload);
}
mAdapter = new AdverisementAdapter(getContext(),mUploads);
mrecyclerView.setAdapter(mAdapter);
}
and Picasso to retreive image:
#Override
public void onBindViewHolder(#NonNull ImageViewHolder imageViewHolder, int i) {
Upload uploadCurrent = mUploads.get(i);
imageViewHolder.textViewName.setText(uploadCurrent.getName());
Picasso.get().load(uploadCurrent.getUrl()).into(imageViewHolder.imageView);
}
Picasso work fine, beacuse except form an image I also get from Firebase string with the name, which is downloaded appropriately. So, the problem I think it's just with this wrong url:
https://firebasestorage.googleapis.com/v0/b/my_name/o?name=image.jpg&uploadType=resumable&upload_id=AEnB2UrrOhqOVqTHuRRVRmlkf4Gh6y5xd_w5IvRok1SNVOMNnz34dqWFJ5_lPD0DNJr05mrHrT8g97sy0d4BZAdiB6v7skkLSQ&upload_protocol=resumable
When I try to entered this link, I receive this kind of error:
Invalid request. X-Goog-Upload-Command header is missing.
You're writing this value to the database:
taskSnapshot.getUploadSessionUri().toString()
This is the URI of the upload session, which you can use to resume an upload in case it gets aborted.
Since you want to store the download URL, this call is pretty useless for your cause. Instead you should call getDownloadUrl() to (asynchronously) get the download URL for the newly uploaded file:
fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(AddAdvertisement.this, "Upload successful!", Toast.LENGTH_LONG).show();
fileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String url = uri.toString();
Upload upload = new Upload(et_localization, url);
String uploadId = mDataBaseRef.push().getKey();
mDataBaseRef.child(uploadId).setValue(upload);
}
});
}
})...
Note that this is quite well described in the Firebase documentation on getting a download URL after uploading a file, which event includes a sample of accomplishing the same by using continueWithTask instead of nesting callbacks (which I did above).
According to the official documentation regarding UploadTask.TaskSnapshot's getUploadSessionUri() method:
Returns the session Uri, valid for approximately one week, which can be used to resume an upload later by passing this value into putFile(Uri, StorageMetadata, Uri).
I'm afraid that this is not the Uri that you are looking for. To get the correct uri, please see my answer from this post.
fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(AddAdvertisement.this, "Upload successful!", Toast.LENGTH_LONG).show();
fileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// just do your task //like hashmaps to put in
}
});
}
})
That did not worked for me (using Expo), but using XMLHttpRequest did. I've found this solution here: https://github.com/expo/expo/issues/2402#issuecomment-443726662
My code is below, in case it can help.
_uploadImageAsync = async (uri) => {
try {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
console.log(e);
reject(new TypeError('Network request failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', uri, true);
xhr.send(null);
});
const ref = firebase
.storage()
.ref()
.child('images/usersPicture/test');
const snapshot = await ref.put(blob);
blob.close();
return await snapshot.ref.getDownloadURL();
} catch(error) {
console.log(error)
}
}

How to Get Image URL after uploading an image form android to Firebase?

I am making an App that user uploaded images on Firebase storage. After Uploading the image i want to upload the Images's URL and other details to my own API. How can i get the Uri of that image which the user just uploaded.
This tutorial teaches how to do the uploading but doesn't show how to get the image URL. I tried all the tutorials but none shows the thing that i want.
According to the documentation, you can call .getDownloadUrl in the .onSuccessListener to get the image URL.
Here is the example from the documentation:
// Get the data from an ImageView as bytes
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = imageView.getDrawingCache();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainsRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
Uri downloadUrl = taskSnapshot.getDownloadUrl();
}
});
You will get the download URL on the onSuccess callback. Check the following code
public static void storeInFirebase(Context context, Uri uri, String type) {
StorageReference riversRef = null;
mStorageRef = FirebaseStorage.getInstance().getReference();
//to create a separate folder with all the pictures uploaded
riversRef = mStorageRef.child("pictures/" + "unique_value");
UploadTask uploadTask = riversRef.putFile(uri);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
DialogUtils.dismissProgressDialog();
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
downloadUrl = taskSnapshot.getDownloadUrl();
Log.d("downloadUrl", "" + downloadUrl);
}
});
}
imagename.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
insertDataFirebase_with_image(UID, String.valueOf(uri));
insertData_with__Image(UID, String.valueOf(uri));
}
});
//here imagename is the StoragePreference that lead to the image location
//nad insert data are function that i have used to store the image URL to my Realtime database

How to get URLs of all images stored in firebase in Android?

I am doing this Android Project in which i want help in retrieving all the URLs which are stored in Firebase Storage and display them all in imageview. The Problem with the given code is that it only fetches one download url.In what way can i get all the URLs for all the images stored in Firebase.
In short: There is one activity in which I am saving the images to firebase and in other i want to retrieve all the images in Imageview.In what way i can do it ?
Thanks
if(requestCode== GALLERY_INTENT && resultCode== RESULT_OK)
{
mProgress.setMessage("Uploading....");
mProgress.show();
Uri uri =data.getData();
StorageReference filepath = mStorage.child("Photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mProgress.dismiss();
Uri downloadUri = taskSnapshot.getDownloadUrl();
Picasso.with(MainActivity.this).load(downloadUri).fit().centerCrop().into(mImageView);
Toast.makeText(MainActivity.this,"Upload done",Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this,"Upload failed",Toast.LENGTH_LONG).show();
}
});
}
I don't think there is an API to fetch all files stored in firebase storage.
When i was saving files , i used to store the file metadata including the file name, download url etc in the real time database.
So when i had to fetch all the files from the storage, i would use the database.
Edit :
Here is how i did it.
UploadTask uploadTask = storageRef.putBytes(data,storageMetadata);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//Save to database using
//taskSnapshot.getMetadata().getCustomMetadata(StringKeys.SOME_KEY);
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
}
});
In Firebase, currently there are no API call that can give you list of all files in Firebase Storage. Instead what you can do is, Once image is uploaded to Firebase Storage, get the download link of that image using getDownloadUrl(); and save it to real-time database.
To read or write data from the database, you need an instance of DatabaseReference:
private DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
To save link of the uploaded image to real time database, you need to create java object such as:
public class Image implements Serializable {
public String downloadUrl;
public Image() {
}
public Image(String dUrl) {
this.downloadUrl = dUrl;
}
}
Once you created java object, Add following lines of code in onSuccess(UploadTask.TaskSnapshot taskSnapshot):
Uri downloadUri = taskSnapshot.getDownloadUrl();
Image image = new Image(downloadUri.toString());
String userId = databaseReference.push().getKey();
databaseReference.child(userId).setValue(image);
This will add download link of that image in real-time database.
Now when you want list of all the images in your Firebase Storage, simply use the following code:
private ArrayList<Data> list;
...
private void getImagesList() {
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
Data data = new Data(childSnapshot.child("downloadUrl").getValue().toString());
list.add(data);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}

Can't write to Firebase Database inside of Firebase Storage onSuccess listener

I am trying to store the Firebase storage URL that I get once I upload a file to Firebase Storage, but for reasons I can't understand, I am unable to write to a location on my Firebase database inside of the Storage onSuccess listener. Any ideas why? If this is not the proper way to store the URL location of the uploaded file then what is?
I can't seem to find an example of this. This is for android.
Thank you
What you are trying to accomplish is completely doable, here's an example
StorageReference fileRef = ....;
Uri fileUri = ....;
UploadTask uploadTask = fileRef.putFile(fileUri);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
Log.d("TAG", "onFailure: " + exception);
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// This is the URL you are looking for, here you should insert it into your db instance...Something like this
Uri downloadUrl = taskSnapshot.getDownloadUrl();
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
dbRef.child("uploadUrls").child("url1").setValue(downloadUrl.toString());
}
});
I hope this helps
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
Log.d("TAG", "onFailure: " + exception);
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// This is the URL you are looking for, here you should insert it into your db instance...Something like this
Uri downloadUrl = taskSnapshot.getDownloadUrl();
addData(downloadUrl.toString());
}
});
public void addData(String downloadUrl)
{
dbRef.child("uploadUrls").child("url1").setValue(downloadUrl);
}

Categories

Resources