I have stored the url of the pdf file stored in firebase storage, in database inside the node Pdf. I am trying to download the file from firebase storage with the help of the url stored inside the database.
public class DownloadFile extends AppCompatActivity{
DatabaseReference databaseReference= FirebaseDatabase.getInstance().getReference();
String root_child="my book";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
databaseReference.child("Pdf").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(root_child))
{
String url=dataSnapshot.child(root_child).getValue().toString();
StorageReference island=storageRef.child("books").child(root_child).child(url);
island.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
pdfView.fromFile(file).load();
}
});
}
}
The problem is nothing really shows up inside the pdf view. When I debug the app I found that StorageReference island=storageRef.child("books").child(root_child).child(url); is not creating the right reference. In short the file is not downloading. Since the file name varies according to what users upload, it is not possible for me to specify the file name hence I used 'child(url)' so that it can search the file using the url but I am not sure if that is the right way to search a file.Any help is appreciated.
As you have discovered while debugging, the file is not downloading because the reference is not correct.
How are you getting info from the user about which file to download ?
I believe you must be showing him the list of files which he/she has uploaded. So in that list you can store the info about the file_name. Now when the user clicks on the list-item, you can have the correct reference since you know the file_name from the clicked list-item.
In the same matter i give you a different approach that i use when i was getting that same error.
actually i save file in Firebase Storage with the name of post_id to which the file is related and then give shot to the following code
give a look
private void downloadFile(final String postKey) {
File cFile = new File(getContext().getCacheDir(), "app Directory");
final File cLocalFile = new File(cFile, postKey);
if (!rootPath.exists()) {
rootPath.mkdirs();
}
if (!cFile.exists()) {
cFile.mkdirs();
}
final FileDownloadTask downloadingTask = mStorage.child(postKey).getFile(cLocalFile);
downloadingTaskProgress(downloadingTask, cLocalFile);
}
private void downloadingTaskProgress(FileDownloadTask downloadingTask, final File cLocalFile) {
downloadingTask.addOnProgressListener(new OnProgressListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onProgress(final FileDownloadTask.TaskSnapshot taskSnapshot) {
double progressSize = (100.0 * taskSnapshot.getBytesTransferred())
/ taskSnapshot.getTotalByteCount();
}
}).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(), "File download complete: " + model.fileName, Toast.LENGTH_SHORT).show();
try {
writeToStorage(cLocalFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(getContext(), "local file not created: " +
exception.toString(), Toast.LENGTH_LONG).show();
}
});
}
private void writeToStorage(File src) throws IOException {
FileChannel inChannel = new FileInputStream(src).getChannel();
FileChannel outChannel = new FileOutputStream(localFile).getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
}
give some modification as per your need and this approach could work as it is in mine....
I got the solution of the problem myself.
I used StorageReference island=storage.getReferenceFromUrl(url); instead of StorageReference island=storageRef.child("books").child(root_child).child(url); . This solved my problem.
Related
I am downloading files from firebase storage
But I can only download one by one
Can I download multiple files at once?
Is it the best way to repeat the same code?
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
StorageReference islandRef = storageRef.child(filename);
final String saveFilename = filename;
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/down/");
// If no folders
if (!dir.exists()) {
dir.mkdirs();
}
final File localFile = new File(dir,saveFilename);
islandRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
Simply call putFile once for each file you want to download. You will need a different reference and local file for each call.
FileDownloadTask task1 = storageRef1.getFile(localFile1);
FileDownloadTask task2 = storageRef2.getFile(localFile3);
FileDownloadTask task3 = storageRef3.getFile(localFile3);
You can then wait for all them to complete with Tasks.whenAll():
Tasks.whenAll(task1, task2, task3)
.addOnSuccessListener(new OnSuccessListener<List<Task<*>>() {
#Override
public void onSuccess(Task task) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
There is no specific API to download multiple files. You'll just have to download them by calling the same API for each file.
okay so the method I have tried is .getfile() for downloading the image. it triggers onsuccess listener as well but I can't locate the file in my internal storage, not sure if I can access it
#Override
public void onDownloadClick(int position) {
Toast.makeText(this, "will try to dwonload XD" , Toast.LENGTH_LONG).show();
Upload selectedItem= mUploads.get(position);
final String selectedkey= selectedItem.getKey();
StorageReference imgRef=mStorage.getReferenceFromUrl(selectedItem.getImageUrl());
try{
File localFIle=File.createTempFile("images", "jpg");
imgRef.getFile(localFIle).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(ImagesActivity.this, "downloaded" , Toast.LENGTH_LONG).show();
Log.d("file ", "filedownloaded");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ImagesActivity.this, "not able to download" , Toast.LENGTH_LONG).show();
}
});
}
catch (Exception e)
{
}
}
It looks like you're creating a File object called localFIle. If you want to know what path that it, just log its string value. If that's not the location you want, try something else. I suggest reading the documentation on locating files on Android devices.
I would like to load an image, from Firebase Storage, to the action bar. I tried using Glide, the same way I would, if I was loading the reference into an ImageView. This wouldn’t work, I did some digging and found a reference to Glide.with(this).load(source).into(new Task){ but I wasn’t sure how to exicute this, or if it would allow me to set the image as an action bar icon/logo. Any advice would be appreciated. I am new to android. I learned java, coding desktop applications with JavaFX. The transition has taken some adjusting, and this has truly stumped me. I felt like their was probably a simple solution, but I am such a novice, it is escaping me. I have hacked at this for a few days, with no luck. I’ll take advice in any form. Thank you.
Immediately after posting this I tried something new, and it worked. Here is the code I used. I downloaded it to a file, and then created a Drawable, from the file.
StorageReference image = storageReference.child(firebaseAuth.getUid()).child("Images").child("Profile_Pic");
try {
final File localFile = File.createTempFile("images", "jpg");
image.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
String pathName = localFile.getPath();
Drawable d = Drawable.createFromPath(pathName);
actionBar.setLogo(d);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(HowItWorksActivity.this, "OOPS", Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
Toast.makeText(HowItWorksActivity.this, "Realy off", Toast.LENGTH_LONG).show();
}StorageReference image = storageReference.child(firebaseAuth.getUid()).child("Images").child("Profile_Pic");
try {
final File localFile = File.createTempFile("images", "jpg");
image.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
String pathName = localFile.getPath();
Drawable d = Drawable.createFromPath(pathName);
actionBar.setLogo(d);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(HowItWorksActivity.this, "OOPS", Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
Toast.makeText(HowItWorksActivity.this, "Realy off", Toast.LENGTH_LONG).show();
}
I have been searching for this problem, but I have not found any solution here. My problem is that when I post new item to firebase storage everything works well, but when I try to download it, directory folder is created successfully, but file is not downloaded as it shows me this error exception:
com.google.firebase.storage.StorageException: Object does not exist at
location
My code here:
#Override
public void onButtonDownloadClick(View view, final int position) {
String name = list.get(position).getRemoteName();
File storagePath = new File(Environment.getExternalStorageDirectory(), "FromFiles");
// Create direcorty if not exists
if(!storagePath.exists()) {
storagePath.mkdirs();
}
final File myFile = new File(storagePath, list.get(position).getRemoteName());
islandRef = storageReference.child(uid).child("files").child(name);
islandRef.getFile(myFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
// Local temp file has been created
Toast.makeText(getActivity(), "Succeed", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
Toast.makeText(getActivity(), exception.toString(), Toast.LENGTH_LONG).show();
}
});
}
});
When I press button, file should be downloaded, however only directory is created.
This is working example for the firebase download and check the download path, the object should exist in the bucket.
// Initialize Storage
//storage
mStorage = FirebaseStorage.getInstance("gs://<bucket_name>");
mStorageRef = mStorage.getReference();
final StorageReference downloadRef;
downloadRef = mStorageRef.getRoot().child(downloadPath);
try {
File output = new File(Environment.getExternalStorageDirectory() + File.separator + Config.MY_VIDEOS_PATH);
if (!output.exists()) {
output.mkdir();
}
localFile = new File(output, downloadId);
} catch (Exception e) {
e.printStackTrace();
}
// Download and get total bytes
downloadRef.getFile(localFile)
.addOnProgressListener(new OnProgressListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onProgress(FileDownloadTask.TaskSnapshot taskSnapshot) {
showProgressNotification(1,title, "",
taskSnapshot.getBytesTransferred(),
taskSnapshot.getTotalByteCount());
}
})
.addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "download:SUCCESS");
// Send success broadcast with number of bytes downloaded
broadcastDownloadFinished(downloadPath, taskSnapshot.getTotalByteCount());
showDownloadFinishedNotification(downloadPath, (int) taskSnapshot.getTotalByteCount());
// Mark task completed
taskCompleted();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.w(TAG, "download:FAILURE", exception);
Log.w(TAG, "download:FAILURE", exception.getCause());
// Send failure broadcast
broadcastDownloadFinished(downloadPath, -1);
showDownloadFinishedNotification(downloadPath, -1);
// Mark task completed
taskCompleted();
}
});
Let us assume that your image.jpg in the photos folder then the downloadPath photos/image.jpg
Check Firebase Rules ..!
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
private FirebaseAuth mAuth;
private FirebaseDatabase mdatabase;
private DatabaseReference mdatabaseReference;
StorageReference mFStorage;
StorageReference filePath;
mAuth = FirebaseAuth.getInstance();
mdatabase = FirebaseDatabase.getInstance();
mdatabaseReference = mdatabase.getReference();
mFStorage= FirebaseStorage.getInstance().getReference();
filePath=mFStorage.child("audio").child(audioId+".mp3");
filePath.putFile(imageGalleryUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
dialog.dismiss();
DownloadUrl=taskSnapshot.getDownloadUrl();
Log.d(TAG,"DownloadUrl.toString()");
//download link for file
}
});
then use Download Manager To download File like for Audio
Context ctx=MainActivty.this;
DownloadManager downloadManager = (DownloadManager)ctx.getSystemService(DOWNLOAD_SERVICE);
//Your Url here
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDescription("Downloading a file");
long id = downloadManager.enqueue(request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("File Downloading...")
.setDescription("Audio File Downloading...!")
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "/Audio/"+audioName+".mp3"));
I uploaded a file to Firebase Storage from my project console. Now, I downloaded that file from my app using the method 'Download to a local file' as mentioned in the Firebase Storage documentation, but I am not able to find the downloaded file on my phone.
Can someone tell me where does that file get downloaded to?
FirebaseStorage firebaseStorage = FirebaseStorage.getInstance();
final StorageReference storageReference = firebaseStorage.getReferenceFromUrl("gs://ldq-app-d2e6b.appspot.com");
button_down.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String fileName = new String(editText_file.getText().toString());
StorageReference childReference = storageReference.child("Quizzes");
StorageReference fileReference = storageReference.child("Quizzes/" + fileName + ".pdf");
File localFile = null;
try {
localFile = File.createTempFile(fileName, "pdf");
}
catch (IOException ioe){
Toast.makeText(getContext(), "File creation failed", Toast.LENGTH_SHORT).show();
}
fileReference.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getContext(),"File downloaded",LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getContext(),"Download failed. Try again!", LENGTH_SHORT).show();
}
});
//Toast.makeText(getContext(),"Button working",LENGTH_SHORT).show();
}
});
As per Firebase Document, they are creating a temporary file for saving Image from Url. Link
File localFile = File.createTempFile("images", "jpg");
If you want to store it on phone's internal memory or in external memory then just create a File with storage path and pass it to FileDownloadTask.
File storagePath = new File(Environment.getExternalStorageDirectory(), "directory_name");
// Create direcorty if not exists
if(!storagePath.exists()) {
storagePath.mkdirs();
}
final File myFile = new File(storagePath,"file_name");
yourStorageRef.getFile(myFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
// Local temp file has been created
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});