'React Native Expo [Unhandled promise rejection: Error: Could not create asset.]

i'm trying to save a base64 image to mobile phone. in expo-media-library i get an unhandled promise error and it does not save image to gallery.

const handleLongPress = async () => {
    console.log(qrName);
    qrSVG.toDataURL((data) => {
      setImageSource("data:image/png;base64," + data);

      console.log("DATA: ", imageSource);
    });
    const base64Code = imageSource.split("data:image/png;base64,")[1];
    const filename = FileSystem.documentDirectory + qrName + ".png";

    await FileSystem.writeAsStringAsync(filename, base64Code, {
      encoding: FileSystem.EncodingType.Base64,
    });
    const mediaResult = await MediaLibrary.saveToLibraryAsync(filename);
    console.log("Result: ", mediaResult);
  };

FileSystem.writeasync() works correctly but when it's in the MediaLibrary.saveToLibraryAsync() it sends an unhandled promise error. Here is the Error:

[Unhandled promise rejection: Error: Could not create asset.]at node_modules\react-native\Libraries\BatchedBridge\NativeModules.js:106:50 in promiseMethodWrapper
at node_modules\expo-modules-core\build\NativeModulesProxy.native.js:15:23 in moduleName.methodInfo.name
at node_modules\expo-media-library\build\MediaLibrary.js:164:7 in saveToLibraryAsync
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:294:29 in invoke
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:155:27 in invoke
at node_modules\regenerator-runtime\runtime.js:190:16 in PromiseImpl$argument_0
at node_modules\react-native\node_modules\promise\setimmediate\core.js:45:6 in tryCallTwo
at node_modules\react-native\node_modules\promise\setimmediate\core.js:200:22 in doResolve
at node_modules\react-native\node_modules\promise\setimmediate\core.js:66:11 in Promise
at node_modules\regenerator-runtime\runtime.js:189:15 in callInvokeWithMethodAndArg
at node_modules\regenerator-runtime\runtime.js:212:38 in enqueue
at node_modules\regenerator-runtime\runtime.js:239:8 in exports.async
at node_modules\expo-media-library\build\MediaLibrary.js:141:7 in createAssetAsync
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:294:29 in invoke
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:155:27 in invoke
at node_modules\regenerator-runtime\runtime.js:165:18 in PromiseImpl.resolve.then$argument_0
at node_modules\react-native\node_modules\promise\setimmediate\core.js:37:13 in tryCallOne
at node_modules\react-native\node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:248:12 in _allocateCallback$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:112:14 in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:166:14 in _callReactNativeMicrotasksPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:418:41 in callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:393:6 in __callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:135:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:370:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:134:4 in flushedQueue


Solution 1:[1]

const handleLongPress = async () => {
    const qrImagesDirectory = FileSystem.documentDirectory + "qrImages/";
    const fileName = qrName + ".png";
    saveQRAsImage(qrImagesDirectory, fileName, imageSource);
  };
const saveQRAsImage = async (qrImagesDirectory, fileName, imageSource) => {
    //Get folder
    const folder = await FileSystem.getInfoAsync(qrImagesDirectory);

    // Check if folder does not exist, create one furthermore
    if (!folder.exists) {
      await FileSystem.makeDirectoryAsync(qrImagesDirectory);
    }

    // Write file into the source of program
    await FileSystem.writeAsStringAsync(
      qrImagesDirectory + fileName,
      imageSource,
      {
        encoding: FileSystem.EncodingType.Base64,
      }
    );
    const ans = await FileSystem.getInfoAsync(qrImagesDirectory + fileName);

    // Make the file accessible through mobile phone
    FileSystem.getContentUriAsync(ans.uri).then((cUri) => {
      //Open save image options
      IntentLauncher.startActivityAsync("android.intent.action.VIEW", {
        data: cUri,
        flags: 1,
      });
    });
  };

this worked for me!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ziya Karagöz