Uploading files to Firebase Storage from Android application - android

I am making an App in Android Studio and I am using Firebase Storage to store user information in individual text files, to later be uploaded to the app's user dashboard. I have written all the code to do this and I have followed the Firebase documentation to the best of my ability. When I run my app (tested on my Motorola moto e5 phone) everything runs perfectly, and then the file with the user information is created. Then it is supposed to be uploaded to the Firebase Storage section, and then it should be destroyed. I know that the first and last events happened.
Problem
However, when I go into Firebase to check that the file is there it is not. So I go to check to see if Android Studio returned any errors and I see no errors and that everything ran smoothly, but I don't see the files in firebase that were supposed to be uploaded. So then I looked all over the internet, fourm after fourm, documentation after documentation, and I tried it all. If you find something that might help me that I haven't found please kindly share the link. Also if you know what the problem is please share.
Troubleshooting Methods
To be more specific these are some things I have tried:
Clean Project
Invalidate Caches and Restart
Change SDK Version in the dependencies in the build.gradle file and made sure they were all up to date and tried old ones too
Wrote the example code they give in the documentation in a different project and it still didn't work
Kept writing code to see if the file was hidden and the Storage Reference returned null
Tried removing the file.delete(); line
Code
This method when called should create a "goal" the user wants to accomplish by saving their input in a file called 0.txt, 1.txt, 2.txt and so on. Then the method should upload the file to Firebase Storage, and that's where the problem is. It won't appear in the database.
private void createGoal(String activity, String timeframe, String number, String unit) throws IOException {
//creates an instance of the Main Dashboard class inorder to access the variable counterString.
MainDashboard dBoard = new MainDashboard();
//Names the 0.txt, 1.txt, 2.txt, and so on
file = new File(dBoard.counterString + ".txt");
//Creates the actual file
file.createNewFile();
//Creates the writer object that will write to the file
FileWriter writer = new FileWriter(file);
//Writes to the text file
writer.write(activity + " : " + "0 / "+ number + " " + unit + " in " + timeframe);
//Closes the Writer
writer.close();
//Creates a Uri from the file to be uploaded
upload = Uri.fromFile(new File(activity + ".txt"));
//Uploads the file exactly as the documentation says, but it doesn't work
UploadTask uploadTask = storageRef.putFile(upload);
//Deletes the file from the local system
file.delete();
}
Any Ideas Are Appreciated.

When you call putFile Firebase starts uploading the data in the background, so that your user can continue to use the app. But your code immediately calls delete on the local file after that, which means you're deleting the local file before Firebase has completed (or possibly even started) uploading it.
The trick is to monitor the upload progress as shown in the Firebase documentation, and only delete the local file once the upload has completed.
Based on the example from that documentation:
// Listen for state changes, errors, and completion of the upload.
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
System.out.println("Upload is " + progress + "% done");
}
}).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
#Override
public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
System.out.println("Upload is paused");
}
}).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) {
// Handle successful uploads on complete
// ...
//Deletes the file from the local system
file.delete();
}
});

Related

Update the file sent in Firebase

I wrote a program that uploads a series of data to firebase
My problem is that when new data is uploaded, the previous contents of the file in Firebase are deleted and new data is replaced.
It is possible to guide the previous data to be added to the new data
enter image description here
String key_press ="key pressed :"+sb;
reference= FirebaseStorage.getInstance().getReference().child("Dcument");
reference.child("file.txt").putBytes(sb.toString().getBytes()).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Toast.makeText(MyAccessibilityService.this, "file upload seuccessfully", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MyAccessibilityService.this, e.toString(), Toast.LENGTH_SHORT).show();
}
});
When you write data to a path in Cloud Storage (with Firebase or any of the other SDKs) it replaces any data that existed at that path. There is no way to tell Cloud Storage to merge the data, as it treats all files/objects as blobs and doesn't have any knowledge about the file's structure.
So you will either have to read the existing data, merge that with your update, and then write the result to Cloud Storage, or store the new data as a separate file in Cloud Storage.

Rescan older files with mediascannerconnection in local storage. files get not updated on windows

My android-application writes a bunch of csv-files and jpg-files to the internal storage of the device. I am using MediaScannerConnection.scanFile() to make the files accessable from my windows-system without rebooting the android-device.
private void scanFiles() {
File targetDirectory = new File(Environment.getExternalStorageDirectory(), "DIR_OF_MY_APP");
if (targetDirectory.exists()) {
List<File> filesToScan = getFiles(targetDirectory);
List<String> filePathsToScan = new ArrayList<>();
for(File file : filesToScan) {
filePathsToScan.add(file.getPath());
}
MediaScannerConnection.scanFile(this, filePathsToScan.toArray(new String[0]), null, new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.d("OK", "Path: " + path);
Log.d("OK", "Uri : " + uri);
}
});
}
}
In my Logcat i can see every file is getting scanned. The new ones and the old ones.
My problem is when my app is adding new lines to an existing csv-file and the file is getting scanned, The new lines do not appear in the csv-file when its opend from my pc. How can i fix this problem?
I already tried to rename all the files from filename to tmp_filename, rescann all the files and rename them back from tmp_filename to filename and rescann them again. After this, i have can see the oldfilename-file and the tmp_oldfilename-file on my windows-computer. The tmp_oldfilename-file can not be opend (Unknown error on [memory-adress]). The oldfilename-file shows the not updated csv-file.
I also tried to use a intent to scan the files, since some questions on so say its going to update them:
for(File file : filesToScan) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
Log.d("OK", "File: " + file.getName() + " scanned...");
}
here i can see the files getting scanned too, but they do not show up updated on my windows-computer.
Okay the only solution i came up with, is to set the usb-mode to load-only (this must be done by hand from the user) before performing the MediaScannerConnection.scanFile();. After this is done, the user can set the usb-mode back to mtp and than the csv-files will show up with the new added lines.
This is a really bad workarround, but still better than rebooting the device. If someone has an better solution, pls share.

How to get the local path from a file downloaded from Firebase Storage

I am a bit confused with the Firebase documentation: https://firebase.google.com/docs/storage/android/download-files
I am trying to download a file from Firebase through the URL of the file and then get its local path:
mStorageReference.getFile(downloadURL).addOnSuccessListener(new
OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
// I assume the file is now downloaded from the given URL and is on the device
// HOW DO I GET THE PATH TO THE FILE ON THE DEVICE ?
}
});
The question is in the comments.
From the docs :-
The getFile() method downloads a file directly to a local device.
So, instead of doing what you're doing, you can first create a temporary file.
Following is an example :-
File localFile = File.createTempFile("images", "jpg");
After that, you pass this localFile as a parameter to your getFile() method ( instead of passing downloadURL ). So, when your onSuccess() is fired, this file is populated with the data that has been downloaded and you can access it for whatever you need. Something like this :-
mStorageReference.getFile(localFile).addOnSuccessListener(new
OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
//localFile contains your downloaded data
}
});
Note that in this example, the localFile is temporary, but you can create a File at your specified path too. It depends on your use case.

Android: delete file taken by camera doesn't work properly (4.4.x)

I delete the file (camera file) like that:
public static void deleteFile(File file) {
if (file != null && file.exists()) {
if (!file.delete()) {
LogUtils.LOGE(TAG, "Delete file failed: " + file.getAbsolutePath());
} else {
LogUtils.LOGD(TAG, "Delete file successful: " + file.getAbsolutePath());
}
}
}
The delete indicates successful, but if I check on Gallery App on my phone, I can see this strange stuff:
It's on my Android 4.4.x. With my another mobile on Android 6.x there is no problem.
Could you help me guys?
As #CommonsWare said, since you are saving your file in the public storage, the gallery app will find the file and keep track, after you remove the gallery needs to update the references to now show the image anymore.
To avoid that you should always save your files in the private storage, you can find more info about storages here: https://developer.android.com/training/basics/data-storage/files.html

Android - Select file from internal storage folder

I have saved a bunch of videos in an internal storage folder. Afterwards, I want the user to be able to select one of these videos in this specific folder. I tried using ACTION_GET_CONTENT in an attempt to let another app do this for me, without any success, as it just opens up a file browser in some other directory.
What I have now is:
public static File getOwnVideosDirectory(Context context) {
String ownVideosDirPath =
context.getFilesDir().getAbsolutePath() + File.separator + "OwnVideos";
File ownVideosDir = new File(ownVideosDirPath);
if (!ownVideosDir.exists()) {
ownVideosDir.mkdirs();
}
return ownVideosDir;
}
private void dispatchExistingVideo() {
Log.d(LOG_TAG, "> dispatchExistingVideo");
Intent videoPicker = new Intent(Intent.ACTION_GET_CONTENT);
File ownVideosDir = Utility.getOwnVideosDirectory(getContext());
videoPicker.setDataAndType(Uri.fromFile(ownVideosDir), "video/*");
if (videoPicker.resolveActivity(getContext().getPackageManager()) != null) {
startActivityForResult(videoPicker, REQUEST_EXISTING_VIDEO);
}
}
So I'm wondering, am I doing something wrong or is it impossible like this. If impossible: is there any library,... available that would allow me to do what I want, or any direction on how I could implement this myself as a last resort?
Thanks in advance
Please take a look at that library - Material File Picker
It allows to show a dialog with the specified path using .withPath(Utility.getOwnVideosDirectory(getContext()).getAbsolutePath()).
The whole creation code:
new MaterialFilePicker()
.withActivity(this)
.withRequestCode(1)
.withFilter(Pattern.compile(".*\\.txt$")) // Filtering files and directories by file name using regexp
.withFilterDirectories(true) // Set directories filterable (false by default)
.withHiddenFiles(true) // Show hidden files and folders
.withPath(Utility.getOwnVideosDirectory(getContext()).getAbsolutePath())
.start();

Categories

Resources