React Native Firebase Storage - getting error when trying to save image with .putFile() - react-native

I am trying to save a local image from the phone to firebase storage but am getting the following error.
Permission Denial: reading com.google.android.apps.photos.contentprovider/........uid=XXXXX requires the provider be exported, or grantUriPermission()
See below code.
await imageRef.putFile(localUri, {contentType: 'image/jpg'}); is where the issue is occuring
const uploadImageAndGetUrl = async (localUri, firebasePath) => {
try {
const imageRef = storage().ref(firebasePath);
await imageRef.putFile(localUri, {contentType: 'image/jpg'});
const url = await imageRef.getDownloadURL();
return url;
} catch (err) {
Alert.alert('Profile.js.....Error getting image url from FB', err);
}
};
Manifest is as follows:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Solution 1:
import RNFetchBlob from 'rn-fetch-blob'
async function getPathForFirebaseStorage (uri) {
if (Platform.OS==="ios") return uri
const stat = await RNFetchBlob.fs.stat(uri)
return stat.path
}
const fileUri = await getPathForFirebaseStorage(file.uri)
const uploadTask = ref.putFile(fileUri)
Solution 2:
import RNFS from 'react-native-fs'
const data = await RNFS.readFile(uri, 'base64')
await ref.putString(data, 'base64')
Note: if above solution do not work then make sure READ_EXTERNAL_STORAGE permissions from the user using the react-native-permissions library

i am not sure if its the source path issue or its something about the permission. Have you added the required permissions to the Manifest.xml file.

Related

How to create a .pdf or .csv file automatically in React Native for Android 11 (or later)

The following code works up to Android 10, it is creating a csv file in the DCIM folder:
import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
export async function saveCSV() {
const permission = await MediaLibrary.requestPermissionsAsync();
if (permission.status != 'granted') {
console.log("Permission not Granted!")
return;
}
// CSVLocation
const directoryUri = FileSystem.documentDirectory;
const fileUri = directoryUri + `formData.csv`;
// Save to DCIM folder
const asset = await MediaLibrary.createAssetAsync(fileUri);
try {
const album = await MediaLibrary.getAlbumAsync('album');
if (album == null) {
console.log("ASSET", asset)
await MediaLibrary.createAlbumAsync('album', asset, true);
} else {
await MediaLibrary.addAssetsToAlbumAsync([asset], album, true)
.then(() => {
console.log('File Saved Successfully!');
})
.catch((err: string) => {
console.log('Error In Saving File!', err);
});
}
} catch (e) {
console.log(e);
}
}
Previously this line of code was executed in another function to create a file in the fileUri used above:
await FileSystem.writeAsStringAsync(fileUri, CSVheader + newInfo);
This issue has been described here: https://github.com/expo/expo/issues/12060
In short: Expo Media library is able to save image/video/audio assets so it will fail with other file types. Weirdly enough it was working fine with .pdf and .csv up to Android 10.
In the link above, and also on stackoverflow there are solutions using StorageAccessFramework. However, the user needs to create a subdirectory inside Downloads every time a file needs to be saved. I would like to make it automatically without any popups (after permission is granted).
The destination folder doesn't matter as long as it is accessible by the user later.

How do I save a document in internal/private app storage from external file system of react native app managed by expo?

I'm able to pickup the document from file system using expo-document-picker but can't figure out a way to save it. Please guide on this.
import * as DocumentPicker from 'expo-document-picker';
import * as FileSystem from 'expo-file-system';
const pickDocument = async () => {
let result = await DocumentPicker.getDocumentAsync({});
console.log(result); // was able to get result here
saveDocument(result);
};
const saveDocument = async (image) => {
const fileUri = `${FileSystem.documentDirectory}${image.name}`;
// const savedImage = await FileSystem.downloadAsync(image.uri, fileUri);
const savedImage = await FileSystem.moveAsync(image.uri, fileUri);
console.log('saved image', savedImage);
};
Read about expo file system, https://docs.expo.dev/versions/v46.0.0/sdk/filesystem/#filesystemdocumentdirectory
but couldn't find a method which helps save the document. Tried FileSystem.moveAsync but it gave below error:
Error: An exception was thrown while calling `ExponentFileSystem.moveAsync` with arguments `(
"file:///var/mobile/Containers/...

Why does React Native says that "group1-shard.bin" file does not exist when it does? (tensorflowjs)

Currently, I'm trying to load my model with this function:
const loadModel = async () => {
const modelJSON = require('../assets/models/model.json');
const modelWeights = require('../assets/models/group1-shard.bin');
const model = await tf
.loadLayersModel(bundleResourceIO(modelJSON, modelWeights))
.catch((e) => {
console.log('Error', e);
});
return model;
};
But when I try to require('../assets/models/group1-shard.bin) react-native says that it is "Unable to resolve module ../assets/models/group1-shard.bin", it also says that the file doesn't exist...
My file structure with the group1-shard.bin file:
This is the full error message:
I think if your code is in App.js you could have used the path ./assets/... instead, and also consider adding the bin files in your metro resolver.assetExts array.

How to create csv file in expo react native

I'm still new to React Native may I know how can I create csv file in react native using expo? I've seen people suggesting expo-file-system as they said it is not recommended to use react-native-fs if using expo but I not sure how to use it. is it using FileSystem.writeAsStringAsync(fileUri, contents, options)?
Here is an example of a function that creates a simple .csv file
I'm using react-native-csv to generate the .csv.
expo-media-library is used to move the file from a folder accessible from the app to a publicly accessible folder.
import { jsonToCSV, readRemoteFile } from 'react-native-csv';
import * as FileSystem from 'expo-file-system';
import * as Permissions from 'expo-permissions';
import * as MediaLibrary from 'expo-media-library';
export async function makeCSV() {
const jsonData = `[
{
"Column 1": "Name",
"Column 2": "Surname",
"Column 3": "Email",
"Column 4": "Info"
}
]`;
const CSV = jsonToCSV(jsonData);
// Name the File
const directoryUri = FileSystem.documentDirectory;
const fileUri = directoryUri + `formData.csv`;
// Ask permission (if not granted)
const perm = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);
if (perm.status != 'granted') {
console.log("Permission not Granted!")
return;
}
// Write the file to system
FileSystem.writeAsStringAsync(fileUri, CSV)
try {
const asset = await MediaLibrary.createAssetAsync(fileUri);
const album = await MediaLibrary.getAlbumAsync('forms');
console.log(album)
if (album == null) {
await MediaLibrary.createAlbumAsync('forms', asset, true);
} else {
await MediaLibrary.addAssetsToAlbumAsync([asset], album, true);
}
} catch (error) {
console.log(error);
}
}

how to download a file from server

i am working with react native project i have a task to doawnload files and store them in local so use RNFS but i have links like this .../api/v1/files/5e6f831588b03d4ba3d9f69c/download where i use it in chrome it start the download but with in react native it didn't download anything
here is my code
const localFile = `${RNFS.DocumentDirectoryPath}/test2.pdf`;
const options = {
fromUrl:
'.../api/v1/files/5e6f831588b03d4ba3d9f69c/download', //... means the server base url the link is totaly right
toFile: localFile,
};
RNFS.downloadFile(options)
.promise.then(() => FileViewer.open(localFile))
.then(() => {
// success
})
.catch(error => {
// error
});
}