Create directory on the internal storage in react native expo

49 Views Asked by At

I am using this two functions below in a react native expo project to stock data in a json file and then stock the file on the internal storage. What this code does is that it ask me for permission to stock inside a folder choosed by me and then stock the file inside this folder. But it doesn't create the folder "ProjectName" before creating the file. I have tried a lot of methods but can't create the folder first then the file. So, what I need is that it creates the folder "ProjectName" then it creates the file inside this folder. Someone got a clue please?

This is the two functions that I've tried :

const saveJSONToFile = async (fileName, jsonData, mimetype) => {
        const directory = FileSystem.documentDirectory + 'my-project/';
        const fileUri = directory + fileName + '.json';
        try {
            await FileSystem.makeDirectoryAsync(directory, { intermediates: true });
            await FileSystem.writeAsStringAsync(fileUri, JSON.stringify(jsonData));
            console.log('File URI:', fileUri);
        } catch (error) {
            console.error('Error saving JSON data:', error);
        }
        await saveFile(fileUri, fileName, mimetype);
    };
const saveFile = async (uri, filename, mimetype) => {
        if (Platform.OS === "android") {
            const permissions = await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync();
            if (permissions.granted) {
                const base64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 });
                await FileSystem.StorageAccessFramework.createFileAsync(permissions.directoryUri+'/ProjectName/', filename, mimetype)
                    .then(async (uri) => {
                        await FileSystem.writeAsStringAsync(uri, base64, { encoding: FileSystem.EncodingType.Base64 });
                    })
                    .catch(e => console.log(e));
            } else {
                await shareAsync(uri);
            }
        } else {
            await shareAsync(uri);
        }
    };
1

There are 1 best solutions below

3
Arthur Neres On

I've passed to the same situation, create the folders when your app startup. The code below solves my problem. Adapt to your problem and place it before any save attempts

  const imageDirectory = fileUtils.getPath('image');
  const videoDirectory = fileUtils.getPath('video');
  const audioDirectory = fileUtils.getPath('audio');
  const cacheDirectory = fileUtils.getPath('cache');
  const documentDirectory = fileUtils.getPath('document');

  const directoryCreateConfig = {
    intermediates: true,
  };

  try {
    const response = await Promise.all([
      FileSystem.getInfoAsync(imageDirectory),
      FileSystem.getInfoAsync(videoDirectory),
      FileSystem.getInfoAsync(audioDirectory),
      FileSystem.getInfoAsync(cacheDirectory),
      FileSystem.getInfoAsync(documentDirectory),
    ]);
    const [image, video, audio, cache, document] = response;
    const directoriesToCreate = [];
    if (!image.exists) {
      directoriesToCreate.push(imageDirectory);
    }
    if (!video.exists) {
      directoriesToCreate.push(videoDirectory);
    }
    if (!audio.exists) {
      directoriesToCreate.push(audioDirectory);
    }
    if (!cache.exists) {
      directoriesToCreate.push(cacheDirectory);
    }
    if (!document.exists) {
      directoriesToCreate.push(documentDirectory);
    }

    await Promise.all(
      directoriesToCreate.map(x =>
        FileSystem.makeDirectoryAsync(x, directoryCreateConfig),
      ),
    );
  } catch (error) {
    await Promise.all([
      FileSystem.makeDirectoryAsync(imageDirectory, directoryCreateConfig),
      FileSystem.makeDirectoryAsync(videoDirectory, directoryCreateConfig),
      FileSystem.makeDirectoryAsync(audioDirectory, directoryCreateConfig),
      FileSystem.makeDirectoryAsync(cacheDirectory, directoryCreateConfig),
      FileSystem.makeDirectoryAsync(
        documentDirectory,
        directoryCreateConfig,
      ),
    ]);
  }