2

I'm trying to save an image to document directory (instead of cache) using react native and react-native-fs library, but instead I get a blank photo.

const localPath = (image) => {
    console.log("Cache directory path is ", image)
    const fileName = image.split('/').pop();
    console.log('Filename is ',fileName)
    const newPath =  'file://' + RNFS.DocumentDirectoryPath + '/' + fileName;
    console.log(newPath)

    // write the file
    RNFS.writeFile(newPath, image, 'base64')
      .then((success) => {
        console.log('IMG WRITTEN!');
        console.log(newPath)
      })
      .catch((err) => {
        console.log(err.message);
      });
    return newPath
  }

So I want to use this newPath

<Image style={styles.image} source={{ uri: newPath }} />

but a blank photo appears..... If I pass the original path, then the photo is displayed.

kidroca
  • 3,480
  • 2
  • 27
  • 44
DTZ
  • 127
  • 1
  • 7

2 Answers2

2

If image is a path to a file just use the copyFile method

const localPath = (image) => {
    console.log('Cache directory path is ', image)
    const fileName = image.split('/').pop();
    console.log('Filename is ', fileName)
    const newPath = `${RNFS.DocumentDirectoryPath}/${fileName}`; // You don't really need the `'file://` prefix
    console.log(newPath);

    // COPY the file
    RNFS.copyFile(image, newPath)
      .then((success) => {
        console.log('IMG COPIED!');
        console.log(newPath);
      })
      .catch((err) => {
        console.log(err.message);
      });

    return newPath
  }

There's also a moveFile that you can use to move the file instead of copying

writeFile is used to write content to a file


Note

The function you use to copy the image and return the newPath is not async - it would return the newPath immediately - possibly before the image is copied to the document directory - this might cause a problem if the <Image> tries to load it before the file is actually there.

I would only return the newPath after the image is actually copied

const localPath = async (image) => {
  const newPath = `${RNFS.DocumentDirectoryPath}/${fileName}`;

  await RNFS.copyFile(image, newPath);

  return newPath;
}

// usage
const uri = await localPath(image); 
kidroca
  • 3,480
  • 2
  • 27
  • 44
0

Well, the following solution worked for me. You have to encode photo to base64 format with react-native-image-base64 package

import ImgToBase64 from 'react-native-image-base64';
const localPath = (image) => {
    console.log("Cache directory path is ", image)
    const fileName = image.split('/').pop();
    console.log('Filename is ', fileName)
    const newPath = 'file://' + RNFS.DocumentDirectoryPath + '/' + fileName;
    console.log(newPath)

    // write the file
    ImgToBase64.getBase64String(image)
      .then(base64String =>

        RNFS.writeFile(newPath, base64String, 'base64')
          .then((success) => {
            console.log('IMG WRITTEN: ', newPath);
          })
          .catch((err) => {
            console.log(err.message);
          }))

      .catch((err) => {
        console.log(err.message);
      });
    return newPath
  }
DTZ
  • 127
  • 1
  • 7
  • 1
    Please check my answer - use copy instead of reading the file then creating a base64 string then writing that down. BTW you could just read the file as base64 string instead - using `RNFS.readFile(image, 'base64').then(base64String => ...` – kidroca Jan 15 '21 at 18:41