Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expo React Native, saving PDF files to Downloads folder

The following code works correctly for image files. But when I'm trying to save PDF file or other not-media formates, I get Could not create asset error.
I understand that expo-media-library is designed to work with media format files. Is there any alternative for expo-media-library to save other files formats?

import * as FileSystem from 'expo-file-system'
import * as Permissions from 'expo-permissions'
import * as MediaLibrary from 'expo-media-library'

const downloadFile = async (uri: string) => {
    const targetUri = FileSystem.documentDirectory + getFileName(uri)

    const downloadedFile = await FileSystem.downloadAsync(uri, targetUri)

    if (downloadedFile.status === 200) {
        if (Platform.OS === 'android') {
            const permission = await Permissions.askAsync(Permissions.MEDIA_LIBRARY)

            if (permission.status !== 'granted') {
                return
            }

            const asset = await MediaLibrary.createAssetAsync(downloadedFile.uri)
            const album = await MediaLibrary.getAlbumAsync('Download')

            await MediaLibrary.addAssetsToAlbumAsync([asset], album, false)
        }
    }
}
like image 997
Maxim Dantes Avatar asked Oct 25 '25 01:10

Maxim Dantes


1 Answers

it works on android device with https://docs.expo.dev/versions/latest/sdk/filesystem/#storageaccessframeworkcreatefileasyncparenturi-string-filename-string-mimetype-string

import * as FileSystem from 'expo-file-system';
import { StorageAccessFramework } from 'expo-file-system';

const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
if (!permissions.granted) {
    return;
}

try {
    await StorageAccessFramework.createFileAsync(permissions.directoryUri, fileName, 'application/pdf')
    .then((r) => {
        console.log(r);
    })
    .catch((e) => {
        console.log(e);
    });
} catch((e) => {
    console.log(e);
});

My pdf is well downloaded !

In my case i had to generate the file from a base64 string. My code :

import * as FileSystem from 'expo-file-system';
import { StorageAccessFramework } from 'expo-file-system';

const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
if (!permissions.granted) {
    return;
}

const base64Data = 'my base 64 data';

try {
    await StorageAccessFramework.createFileAsync(permissions.directoryUri, fileName, 'application/pdf')
        .then(async(uri) => {
            await FileSystem.writeAsStringAsync(uri, base64Data, { encoding: FileSystem.EncodingType.Base64 });
        })
        .catch((e) => {
            console.log(e);
        });
} catch (e) {
    throw new Error(e);
}
like image 193
RenishV8 Avatar answered Oct 26 '25 14:10

RenishV8