Closed anshul0410 closed 2 years ago
@alariej yep, is planned for this or next week :)
Thanks @RonRadtke
Meanwhile, I was reading a lot about this issue as many other users face it with
pickers
and found a post that said the he usedstat
and just took the actual file uri through this. I tried it and it did work (i.e. the actual video did upload):const stat = await ReactNativeBlobUtil.fs.stat(el.uri); el.uri = stat.path;
Was that just a lucky coincidence? Maybe because it was in
Movies
?
I wonder if this can be a solution (no need to copy anything) or it will fail in many other cases/devices/Android versions/etc,
Thanks.
@RonRadtke I just tried it in a tablet, picking (with image-picker
) an mp4 video from the Downloads
folder which I downloaded previously from Google.
I get this error, is there any way to solve this? Because it will not get the actual file to download as video and we are again at ground zero with our app :-) :
Note: I even used decodeURIComponent(el.uri)
The strange thing is that the behavior is different (it works) in my Android phone, while both have Android 11 version.
I assume they have a different way to store the "Downloaded from Google" video file.
@afilp it's released!
The issue with stat is what I described earlier. There is no guarantee for the row actually pointing to a file. And the issue you're seeing here is exactly that. There is no way to solve that except for switching to the newly introduced APIS
I'll reopen the issue again - just in case you have feedback. If there are any new bugs - please create a new issue though
Thanks Ron!
Maybe you missed to type the related code
here?
@afilp it's released!
The issue with stat is what I described earlier. There is no guarantee for the row actually pointing to a file. And the issue you're seeing here is exactly that. There is no way to solve that except for switching to the newly introduced APIS
With your new v0.14 we do not need to do anything else other than use it, correct? Not sure what you meant with except for switching to the newly introduced APIS
. This is done on v0.14, correct? Or we have to manually do something more? Thanks!
Also, I tried to update the Wiki but I do not have update permissions:
From:
let destpath = ReactNativeBlobUtil.dirs.CacheDir
To:
let destpath = ReactNativeBlobUtil.fs.dirs.CacheDir
(there is a missing fs
there, I believe)
Maybe you would like to change this.
Thanks Ron!
Maybe you missed to type the related
code
here?
no, that's exactly want I meant to write. You get a database row (or multiple) from a query. But probably it would be better to write cursor instead of row, since we get a cursor not a single row.
@afilp it's released! The issue with stat is what I described earlier. There is no guarantee for the row actually pointing to a file. And the issue you're seeing here is exactly that. There is no way to solve that except for switching to the newly introduced APIS
With your new v0.14 we do not need to do anything else other than use it, correct? Not sure what you meant with
except for switching to the newly introduced APIS
. This is done on v0.14, correct? Or we have to manually do something more? Thanks!
You need to use the new functionality. it's not a replacement for the old one, it's an addition. So you will have to call the correct functions as described in the wiki.
Ι tested it in both my Android phone and tablet and worked perfectly!
Thanks a lot!
Hi @RonRadtke, thank you for working so actively on this library. It's been really useful for developers like me who aren't familiar with native Android code. You have no idea how happy I was to see v0.14 released this morning!
On that note, I've been trying to get v0.14 to work on Android 7 but I'm having issues. I'm thinking one of the issues might be in this method from ReactNativeBlobUtilMediaCollection.java
(added my questions as comments in the code):
public static Uri createNewMediaFile(FileDescription file, MediaType mt) {
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
...
} else {
File directory = Environment.getExternalStoragePublicDirectory(relativePath);
if (directory.canWrite()) {
File f = new File(relativePath + '/' + file.getFullPath()); // <-- Instead of relativePath, should it be directory.getPath() instead? Right now this seems to be causing the createNewMediaFile method to return null
if (!f.exists()) {
boolean result = f.mkdirs(); // <-- Should this be f.createNewFile() instead? Right now it's creating a folder
if (result) return Uri.fromFile(f);
}
}
}
return null;
}
I tried replacing making the following replacements and the file got created successfully in the public downloads folder:
directory.getPath()
instead of relativePath
f.createNewFile()
instead of f.mkdirs()
However this led to another problem in the writeToMediaFile()
method:
Here's a relevant snippet of my React Native code:
ReactNativeBlobUtil
.config({
fileCache: true,
path: `${Platform.OS === 'ios'
? ReactNativeBlobUtil.fs.dirs.DocumentDir
: ReactNativeBlobUtil.fs.dirs.DownloadDir
}/${filename}`,
})
.fetch('GET', url, {...})
.then(async (res) => {
if (Platform.OS === 'ios') {
...
} else {
const result = await ReactNativeBlobUtil.MediaCollection.copyToMediaStore(
{
name: 'TestFile',
parentFolder: '',
mimeType: 'application/pdf',
},
'Download',
res.path(),
);
}
});
With this implementation, the file gets saved properly to the app's scoped "Download" directory but doesn't get copied to the shared storage "Download" directory.
I'm not sure if this is considered a new bug. If it is, I'll create a new issue as requested.
Hi @jaedontym, thank you very much for appreciating my work here. It really helps to now people do like and sue my work. And thanks for the bug report. You're partly right. I absolutely forgot to actually create the file. I'm currently only creating the parent directories, but we have to create these too, we can't just only create the file. This will otherwise lead to an error if the parent directory doesn't exist. I am working on a fix for it, I just want to test it first since I did some more clean up and adding that the write method works for older APIs too.
@RonRadtke Thank you so much. Can't wait to integrate the updates to get my app working properly with the newer Android versions! I'll continue reporting relevant bugs here as I find them :)
@RonRadtke Just to make sure, the pickers store the files in the "Cache", right? So this gets bigger and bigger? Or is it automatically cleaned when closing the app, etc.?
I am asking in case I have to manually delete the selected images/videos after the user uploads them to the server, using react-native-blob-util
.
If yes, should I use this method of yours? ReactNativeBlobUtil.fs.unlink
or ReactNativeBlobUtil.fs.mv
?
Thanks!
Yes that will grow. Unlink would be the way to go.
I'm facing problem with copyToMediaStore , I get this error : Failed to get output stream
here is my code
const result =
await ReactNativeBlobUtil.MediaCollection.copyToMediaStore(
{
name: eventTitle,
parentFolder: '',
mimeType: 'application/pdf', // MIME type of the file
},
'Download',
${filePath}
,
);
and filePath is : /storage/emulated/0/Android/data/com.runofshow/files/Download/Test.pdf
Yes that will grow. Unlink would be the way to go.
I tried this, but when I reload the app I still see the photo there in the UI (it should have been a "missing image").
formData.forEach(el => {
if (el.origPath) {
ReactNativeBlobUtil.fs.unlink(el.origPath);
}
});
This is the code for the origPath
:
formData.push({
name,
filename,
type: el.type,
origPath: el.uri,
// Change BASE64 encoded data to a file path with prefix `ReactNativeBlobUtil-file://`.
// Or simply wrap the file path with ReactNativeBlobUtil.wrap().
data: ReactNativeBlobUtil.wrap(
decodeURIComponent(
Platform.OS === 'ios' ? el.uri.replace('file://', '') : el.uri,
),
),
});
Is unlink
working? (it does not seem so)
UPDATE: I do see the photo in the UI, but when trying to re-upload it it shows as missing. So why the UI shows it while it is not there?
What type is the response data, is it always a boolean? (could not find that in docs) I am using JSON.parse as I though it can also be an object and I need to return it back to react-query:
So, what should we expect for "data" there? Thanks! (on uploading success I mean)
UPDATE: I do see the photo in the UI, but when trying to re-upload it it shows as missing. So why the UI shows it while it is not there?
Which UI?
So, what should we expect for "data" there? Thanks! (on uploading success I mean)
Whatever your server sends. The data is the raw value your server is sending, or, if your config is specifying to store it in a file, the path.
So depending on what your goal is, it might be better to use the text()
or json()
since this will resolve a file path and return the data sent by the server.
@RonRadtke Hi Ron! How are the fixes coming along? I hope that no additional complications arose 😰
I went ahead with the app internal storage implementation first but this is affecting the UX of downloading and uploading files quite a bit (most users don't know how to navigate to the directory). Fortunately that's not the app's main feature but I do hope to be able to get this sorted out in time.
As always, really appreciate your work to keep rn-fetch-blob
alive and up-to-date even with your busy schedule!
@jaedontym sorry I had 2 exams and some private issues so I got kinda delayed. But I think I got it fixed, I will run some more tests tomorrow and if these are fine I'll craft a new release.
@RonRadtke I hope your exams went smoothly and your private issues get resolved. Take care, Ron 🙏
@jaedontym Update is released
@HagarAyad the update I released yesterday might fix your problem too. I found a way to reproduce it and fixed it - but I of course can't promise there isn't anything else wrong (e.g. another app modifying the file or so) @jaedontym thanks! The function should now work as expected and also work on android < 10. With the next update I plan to bring back the old environment paths that should enable being able to write to the public download folder on old devices agian. @afilp how's it going? everything working well with that part of the lib?
@RonRadtke Yes, all seems well in Android now! I did not even need that fix, most likely because our users have recent Android versions, but of course it is nice to have this too!
My other (unrelated) problem is when users pick in iOS many heavy images through the picker (8MB each for example) and I show them in a Flatlist. When there are 15+ of them, I have reports that the app is crashing when scrolling to the end of the list.
If you happen to know how to cope with this issue I will greatly appreciate it! I am thinking of using react-native-resizer
, create duplicate smaller images as thumbnails, to show these in Flatlist, while using react-native-blob-util
to upload the original large images one-by-one. But all this is a hassle, Android does not crash, not sure if there is another way in iOS.
Hi, thanks for maintaining this project. i have more of a query than a bug to report. i'm using version 0.13.8 of this library and implementing scope storage related updates in my RN app. Is there a way to download files directly to common download path for android, currently file download is happening in app specific internal storage, which might not be very intuitive for users in general. Is there a plan to implement MediaStore API to make use of download path, or is there any other solution to do so? Any help or suggestion is much appreciated. Thanks.