Firebase download file on listview - android

I am making an app to list the uploaded files and then I want to download them with an setOnItemLongClickListener.I get download url and use it to get reference for the download process.When I click on a listview item,it says download is succesful.But I can not see the file on my phone.Actually I have no idea about where it should be.
I saw similar questions but I could not find a solution.I really need help to solve this problem.
Here is my code:
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3) {
try {
storage = FirebaseStorage.getInstance().getReferenceFromUrl(fileFirebase.get(index).toString());
StorageReference island=storage;
final File file = File.createTempFile("images", "jpg");
island.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(),"Download is succesful!",Toast.LENGTH_LONG).show();
}
}).addOnProgressListener(new OnProgressListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onProgress(FileDownloadTask.TaskSnapshot taskSnapshot) {
//taskSnapshot.getBytesTransferred();
//taskSnapshot.getTotalByteCount();
}
});}
catch (IOException e) {
e.printStackTrace();
}

File.createTempFile stores the file in the internal cache directory of Android.
You should new File instead and it will be available within the scope of your application directory.
If you are using rooted device or emulator, you can check /data/data/<package-name> to see your downloaded file.
And if not rooted, you can browse through ADB shell to this location. In Android Studio 3 you have a built in File explorer to explore the internal data directory of your App which is /data/data/<package-name>.
You may also consider storing the file if in the external storage. For this, you need to declare permission in the Manifest file.
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
Check this link for more information: https://developer.android.com/training/data-storage/files.html

You can get download directory on the device using Environment.getExternalStoragePublicDirectory, see below ...,
For Firebase cloud storage - file upload, download and delete examples, you can see http://www.zoftino.com/firebase-cloud-storage-upload-download-delete-files-android-example#download-file
String DOWNLOAD_DIR = Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_DOWNLOADS).getPath();
StorageReference storageRef = firebaseStorage.getReference();
StorageReference downloadRef = storageRef.child(storageFile);
File fileNameOnDevice = new File(DOWNLOAD_DIR+"/"+fileName);
downloadRef.getFile(fileNameOnDevice).addOnSuccessListener(
new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.d("File download", "downloaded the file");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.e("File download", "Failed to download the file");
}
});

Related

Downloaded files from firebase storage aren't readable

i succesfully download files from firebase storage and save it but the downloaded file which is pdf type isn't openable
here is the method
#Override
public void download(Book book) {
FirebaseStorage storage = FirebaseStorage.getInstance();
File root = new File(Environment.getExternalStorageDirectory(),"Books");
if(!root.exists()){
root.mkdir();
}
storage.getReference().child(book.getmTitle()+".pdf").getFile(new File(root,book.getmTitle())).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(),"Downloaded successfully",Toast.LENGTH_LONG).show();
}
});
}
i am sure that the book.getmTitle() returns the reference name without the extension 'pdf'
Stupid mistake, all what i had to do is to add the extension to the file name

Creating multiple files programmatically on Android through the Google Drive API often creates duplicates?

I am trying to upload files from the internal storage to a user's Google Drive through the API, to back up user data. What I have done so far works on occasion, but it often creates two or three copies of the files as well and I have no idea why.
As far as I know there is no way to upload entire folders and their contents at once, so instead I first create an empty backup folder, then iterate through the user data and copy the files into the folder one by one.
Note: for now I am using the root folder of the Google Drive instead of the App folder that is dedicated for this purpose. This makes it easier to see the files that are created. When everything works, I'll swap the root folder with the app folder.
Creating a new backup first starts with looking for existing backup folders and deleting them if there are any:
private void createNewBackup(Context context, GoogleSignInAccount googleSignInAccount) {
// Create query to search for existing backup folder
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, "Backup"))
.build();
Drive.getDriveResourceClient(context, googleSignInAccount).query(query)
// if a backup folder is found, delete it:
.addOnSuccessListener(new OnSuccessListener<MetadataBuffer>() {
#Override
public void onSuccess(MetadataBuffer metadata) {
// there are never 2 backup folders, so it is always the first set of metadata, hence get(0).
DriveFolder backupfolder = metadata.get(0).getDriveId().asDriveFolder();
Drive.getDriveResourceClient(context, googleSignInAccount).delete(backupfolder)
// when the folder is deleted, create a new backup folder
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
createBackupFolder(context, googleSignInAccount);
}
});
}
})
// if no backup folder is found, create a new backup folder
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
createBackupFolder(context, googleSignInAccount);
}
});
}
When the old backup folder is deleted, this is the code that creates the new backup folder
public void createBackupFolder(Context context, GoogleSignInAccount googleSignInAccount) {
// Get the root folder of the drive:
Drive.getDriveResourceClient(context, googleSignInAccount).getRootFolder().addOnSuccessListener(new OnSuccessListener<DriveFolder>() {
#Override
public void onSuccess(DriveFolder driveFolder) {
// create backup folder in root folder:
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("Backup")
.setMimeType(DriveFolder.MIME_TYPE)
.setStarred(true)
.build();
Log.d("Test", "Creating backup folder");
Drive.getDriveResourceClient(context, googleSignInAccount).createFolder(driveFolder, changeSet)
.addOnSuccessListener(new OnSuccessListener<DriveFolder>() {
#Override
public void onSuccess(DriveFolder backupFolder) {
Log.d("Test", "Created backup folder");
writeDataToBackupFolder(context, googleSignInAccount, backupFolder);
}
})
// if the folder couldn't be created:
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("Test", "failed to create backup folder");
}
});
}
});}
And then finally the files in the subfolders "premium" and "shifts" are copied to the backup folder on the drive with the writeDataToBackupFolder method:
public void writeDataToBackupFolder(Context context, GoogleSignInAccount googleSignInAccount, DriveFolder backupFolder) {
// iterate over the files in the subfolders
File[] subfolders = new File(context.getFilesDir().getPath()).listFiles();
for (int i = 0; i < subfolders.length; i++) {
if (subfolders[i].getName().equals("premium") || subfolders[i].getName().equals("shifts")) {
File[] filesInSubfolder = new File(subfolders[i].getPath()).listFiles();
for (int j = 0; j < filesInSubfolder.length; j++) {
// for every file, get its contents and write them to a file and upload it to the drive
String fileName = subfolders[i].getName() + "/" + filesInSubfolder[j].getName();
List<String> content = readFromFile(context, fileName);
Drive.getDriveResourceClient(context, googleSignInAccount).createContents().addOnSuccessListener(new OnSuccessListener<DriveContents>() {
#Override
public void onSuccess(DriveContents driveContents) {
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
for (int k = 0; k < content.size(); k++) {
writer.write(content.get(k));
writer.write("\n");
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(fileName)
.setMimeType("text/plain")
.setStarred(true)
.build();
Log.d("Test", "Creating file "+fileName);
Drive.getDriveResourceClient(context, googleSignInAccount).createFile(backupFolder, changeSet, driveContents)
.addOnSuccessListener(new OnSuccessListener<DriveFile>() {
#Override
public void onSuccess(DriveFile driveFile) {
Log.d("Test", "Created file "+fileName);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("Test", "Failed to create "+fileName);
}
});
}
});
}
}
}}
It deletes the old backup folder and creates the new backup folder just fine and it always copies the files to the Google Drive. They are all text files, but sometimes (more often than not) duplicates are created. For example, the folder 'premium' has files 1.txt, 2.txt, 3.txt, etc., but on the drive they would appear as premium/1.txt, premium/1.txt, premium/2.txt, premium/3.txt, premium/3.txt, and I have no idea why. Which files become duplicates is random and can change everytime I call the createNewBackup method. As you can see in the code, I register created files in the log, but no duplicates show up there, only on the Drive. Is it a problem with the Google Drive API? Am I calling everything too quickly? How could I stop this from happening?
Never mind. Even though the duplicates problem has not been solved yet, it does not really pose a problem, because when I restore a backup, all the user files are overwritten, so it does not matter if that happens once or twice extra.

How to get all files from firebase storage?

I have uploaded some files into Firebase directory and I want to list them and download one by one.There is no API/Documentation fo this.Could you help me ?
As of July 2019, version 18.1.0 of the Cloud Storage SDK now supports listing all objects from a bucket. You simply need to call listAll() in a StorageReference:
StorageReference storageRef = FirebaseStorage.getInstance().getReference();
// Now we get the references of these images
storageRef.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
#Override
public void onSuccess(ListResult result) {
for(StorageReference fileRef : result.getItems()) {
// TODO: Download the file using its reference (fileRef)
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception exception) {
// Handle any errors
}
});
If you want to download these files, you can use one of the options shown in the Docs.
Please note that in order to use this method, you must opt-in to version 2 of Security Rules, which can be done by making rules_version = '2'; the first line of your security rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
first , you should get the file download Url to retrieve it, the easiest way is to upload a file and generate the download Url in your database, so after that you just go and retrieve each file from the storage like this :
private void downloadFile() {
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("<your_bucket>");
StorageReference islandRef = storageRef.child("file.txt");
File rootPath = new File(Environment.getExternalStorageDirectory(), "file_name");
if(!rootPath.exists()) {
rootPath.mkdirs();
}
final File localFile = new File(rootPath,"imageName.txt");
islandRef.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.e("firebase ",";local tem file created created " +localFile.toString());
// updateDb(timestamp,localFile.toString(),position);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.e("firebase ",";local tem file not created created " +exception.toString());
}
});
}
I personally use this method, whenever you upload a file, save its download URL in your Firebase Database, if you are uploading multiple files then save it in an array. There is no method for Firebase Storage android to download and upload multiple files in one go.
Whenever you want to download files access your firebase database for those URL's.

Android - Download File from Firebase by means of only URL

I'm developing a simple Android application that downloads a file from Firebase storage.
Is there any way to download a file getting only a link to the file? I found a few methods but they were requiring also the name of file
I don't know the name of downloading file, I need to download the file knowing only its URL.
Just try this :
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference httpsReference = storage.getReferenceFromUrl("YOUR_FIREBASE_STORAGE_URL");
File localFile = File.createTempFile("PREFIX_FILE", "SUFFIX_FILE");
httpsReference.getFile(localFile).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
}
});
Firebase Storage documentation.

Android : download files list from Firebase storage

I uploaded a file list to Firebase that I want to download using my app.
List<String> childsRef = new ArrayList<>();
childsRef.add("xxxx/img1");
childsRef.add("xxxx/img2");
... etc
Then, through this list, I try to download files using my Firebase storageReference :
for (String child : childsRef) {
islandRef = storageRef.child(child);
File localFile = File.createTempFile("images", "jpg");
islandRef.getFile(localFile).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
}
});
}
The download process is async, so I can't show pop-ups to visualize downloading progression... I want to navigate to next Activity only if all of pending downloads are done..
Do you have any ideas/help?
--EDIT
Solution :
FirebaseStorage instance = FirebaseStorage.getInstance();
StorageReference referenceFromUrl = instance.getReferenceFromUrl("gs://xxxxxxx.appspot.com/");
for (final String aur : aurl) {
final File localFile = new File(PATH + aur.substring(aur.lastIndexOf("/") + 1, aur.lastIndexOf(".")) + ".dat");
StorageReference f = referenceFromUrl.child(aur);
FileDownloadTask task = f.getFile(localFile);
task.addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
size += localFile.length();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.e("firebase ", ";local tem file not created created " + exception.toString());
}
});
while (!task.isComplete()) {
}
publishProgress("" + (int) ((float) i++ * 100 / aurl.length));
}
getFile returns a FileDownloadTask object, which is a subclass of Task. As you probably know, this Task tracks the progress of the download. You have the option of kicking off all the downloads at once, collecting all the Tasks in a list, then using Tasks.whenAll() to get a new Task that completes when all the downloads are complete.
I have a four part blog series about using Tasks that might help you better understand how they work.
make childsRef hashmap and add a boolean to see if download is completed.
set value true when onSuccess and make a handler to send message when a download completed to check if all boolean values true. than start your activity from handler.

Categories

Resources