Giter Site home page Giter Site logo

alpha0010 / react-native-file-access Goto Github PK

View Code? Open in Web Editor NEW
282.0 6.0 18.0 981 KB

Filesystem access for React Native

License: MIT License

Kotlin 23.09% JavaScript 2.62% Java 9.91% TypeScript 27.19% Swift 17.17% C 0.15% Objective-C 5.49% Ruby 4.30% Objective-C++ 10.07%
react-native filesystem

react-native-file-access's Introduction

react-native-file-access

npm

Filesystem access for React Native. Supports saving network requests directly to the filesystem. Supports Android scoped storage, a requirement when targeting API 30 or higher.

Installation

npm install react-native-file-access
cd ios && pod install

Apple restricts usage of certain privacy sensitive API calls. If you do not use disk space measurements or file timestamps, define the following variable in your Podfile to exclude restricted API calls. More details.

$RNFANoPrivacyAPI = true

If the app does not use autolinking, continue to the manual install instructions in the wiki.

Compatibility

React Native react-native-file-access
<= 0.64 1.x.x
0.65+, old arch 2.x.x, 3.x.x
0.71+, new arch 3.x.x

Usage

import { Dirs, FileSystem } from 'react-native-file-access';

// ...

const text = await FileSystem.readFile(Dirs.CacheDir + '/test.txt');

Directory constants.

  • Dirs.CacheDir
  • Dirs.DatabaseDir (Android only)
  • Dirs.DocumentDir
  • Dirs.LibraryDir (iOS & MacOS only)
  • Dirs.MainBundleDir
  • Dirs.SDCardDir (Android only)
    • Prefer FileSystem.cpExternal() when possible.

Functions.

FileSystem.appendFile(path: string, data: string, encoding?: 'utf8' | 'base64'): Promise<void>

  • Append content to a file.
    • Default encoding of data is assumed utf8.

FileSystem.concatFiles(source: string, target: string): Promise<number>

  • Append a file to another file. Returns number of bytes written.

FileSystem.cp(source: string, target: string, onProgress?: (bytesCopied: number, contentLength: number, done: boolean) => void): Promise<void>

  • Copy a file.

FileSystem.cpAsset(asset: string, target: string, type?: 'asset' | 'resource'): Promise<void>

  • Copy a bundled asset file.
    • Default type is asset. Prefer this when possible.
    • resource uses the Android res/ folder, and inherits the associated naming restrictions.

FileSystem.cpExternal(source: string, targetName: string, dir: 'audio' | 'downloads' | 'images' | 'video'): Promise<void>

  • Copy a file to an externally controlled location.
    • On Android API level < 29, may require permission WRITE_EXTERNAL_STORAGE.
    • On iOS, consider using Dirs.DocumentDir with UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace enabled.

FileSystem.df(): Promise<{ internal_free: number, internal_total: number, external_free?: number, external_total?: number }>

  • Check device available space.

FileSystem.exists(path: string): Promise<boolean>

  • Check if a path exists.
FilesSystem.fetch(
  resource: string,
  init: { body?: string, headers?: { [key: string]: string }, method?: string, network?: 'any' | 'unmetered', path?: string },
  onProgress?: (bytesRead: number, contentLength: number, done: boolean) => void
): Promise<FetchResult>

type FetchResult = {
  headers: { [key: string]: string };
  ok: boolean;
  redirected: boolean;
  status: number;
  statusText: string;
  url: string;
}
  • Save a network request to a file.
    • resource - URL to fetch.
    • init.path - Optional filesystem location to save the response.
    • init.network - Optional restriction on network type. Specifying unmetered will reject the request if unmetered connections (most likely WiFi) are unavailable.
    • onProgress - Optional callback to listen to download progress. Events are rate limited, so do not rely on done becoming true. contentLength is only accurate if the server sends the correct headers.
FilesSystem.fetchManaged(
  resource: string,
  init: { body?: string, headers?: { [key: string]: string }, method?: string, network?: 'any' | 'unmetered', path?: string },
  onProgress?: (bytesRead: number, contentLength: number, done: boolean) => void
): ManagedFetchResult

type ManagedFetchResult = {
  cancel: () => Promise<void>;
  result: Promise<FetchResult>;
}
  • Save a network request to a file.
    • Similar to fetch(), with the option to cancel before completion.

FilesSystem.getAppGroupDir(groupName: string): Promise<string>

  • Get the directory for your app group (iOS & MacOS only).
    • App groups are used on iOS/MacOS for storing content, which is shared between apps.
    • This is e.g. useful for sharing data between your iOS/MacOS app and a widget or a watch app.

FilesSystem.hash(path: string, algorithm: 'MD5' | 'SHA-1' | 'SHA-224' | 'SHA-256' | 'SHA-384' | 'SHA-512'): Promise<string>

  • Hash the file content.

FilesSystem.isDir(path: string): Promise<boolean>

  • Check if a path is a directory.

FileSystem.ls(path: string): Promise<string[]>

  • List files in a directory.

FileSystem.mkdir(path: string): Promise<string>

  • Make a new directory.
    • Returns path of created directory.

FileSystem.mv(source: string, target: string): Promise<void>

  • Move a file.

FileSystem.readFile(path: string, encoding?: 'utf8' | 'base64'): Promise<string>

  • Read the content of a file.
    • Default encoding of returned string is utf8.

FileSystem.readFileChunk(path: string, offset: number, length: number, encoding?: 'utf8' | 'base64'): Promise<string>

  • Read a chunk of the content of a file, starting from byte at offset, reading for length bytes.
    • Default encoding of returned string is utf8.
FileSystem.stat(path: string): Promise<FileStat>

type FileStat = {
  filename: string;
  lastModified: number;
  path: string;
  size: number;
  type: 'directory' | 'file';
}
  • Read file metadata.

FileSystem.statDir(path: string): Promise<FileStat[]>

  • Read metadata of all files in a directory.

FileSystem.unlink(path: string): Promise<void>

  • Delete a file.

FileSystem.unzip(source: string, target: string): Promise<void>

  • Extract a zip archive.

FileSystem.writeFile(path: string, data: string, encoding?: 'utf8' | 'base64'): Promise<void>

  • Write content to a file.
    • Default encoding of data is assumed utf8.

Utility functions.

Util.basename(path: string, separator?: string): string

  • Get the file/folder name from the end of the path.
    • Default path separator is /.

Util.dirname(path: string, separator?: string): string

  • Get the path containing the file/folder.
    • Default path separator is /.

Util.extname(path: string, separator?: string): string

  • Get the file extension.
    • Default path separator is /.

Scoped storage.

For simple usage, use FileSystem.cpExternal() to submit files to general scoped storage categories.

Most functions in this library work with content:// Android resource uris. To gain access to a resource uri, currently use a library such as react-native-document-picker or react-native-scoped-storage. Eventually this library will incorporate file/folder selector functionality (pull requests welcome).

Note:

  • When generating a scoped storage resource uri, use the helper AndroidScoped.appendPath(dir, 'data.txt'), not dir + '/data.txt'.
  • Android may change the name of created files/folders.

AndroidScoped.appendPath(basePath: string, segment: string): string

  • Append a path segment to an Android scoped storage content uri.

Testing

For ease of testing, this library contains a mock implementation: jest/react-native-file-access.ts. To use, copy it into the __mocks__ folder, modifying if needed.

Alternatives

This library aims to be a modern implementation of filesystem api, using Kotlin/Swift and latest best practices. For a more established library, consider:

For more greater control over network requests, consider react-native-blob-courier.

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT

react-native-file-access's People

Contributors

alpha0010 avatar andarius avatar dulmandakh avatar flogy avatar marvedog avatar mateusz1913 avatar megamaddin avatar menssen avatar mysport12 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-native-file-access's Issues

Android build failing with error: Unresolved reference: uri

react-native: "^0.69.3",
react-native-file-access: "^2.4.4",

Platform: Android

Bug

> Task :react-native-file-access:compileDebugKotlin FAILED

error Failed to install the app. Make sure you have the Android development environment set up: https://reactnative.dev/docs/environment-setup.
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
e: /home/shivam/ziki-tunes/music-app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (10, 17): Unresolved reference: documentfile
e: /home/shivam/ziki-tunes/music-app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (484, 19): Unresolved reference: DocumentFile
e: /home/shivam/ziki-tunes/music-app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (494, 23): Unresolved reference: DocumentFile
e: /home/shivam/ziki-tunes/music-app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (497, 75): Unresolved reference: uri

To reproduce
Install this library with latest react native version

Details
Not sure what else to put

Compiling for iOS 10.0 error

Hi! This issue is related to #44. Encountered an error compiling in Xcode 13.4

Compiling for iOS 10.0, but module 'ZIPFoundation' has a minimum deployment target of iOS 12.0

As I understand, ZIPFoundation 0.9.12 requires iOS 12.0 and 0.9.11 requires iOS 11.0. Since this lib specified s.dependency "ZIPFoundation", "< 0.9.12", I bumped the ios platform requirement to 11.0 and it fixed my issue

Here is the diff that solved my problem (disregard the podfile version bump):

diff --git a/node_modules/react-native-file-access/react-native-file-access.podspec b/node_modules/react-native-file-access/react-native-file-access.podspec
index 919300c..c69ef5f 100644
--- a/node_modules/react-native-file-access/react-native-file-access.podspec
+++ b/node_modules/react-native-file-access/react-native-file-access.podspec
@@ -4,17 +4,18 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
 
 Pod::Spec.new do |s|
   s.name         = "react-native-file-access"
-  s.version      = package["version"]
+  # s.version      = package["version"]
+  s.version      = "2.4.2.patch-1" # just to refresh cocoapods
   s.summary      = package["description"]
   s.homepage     = package["homepage"]
   s.license      = package["license"]
   s.authors      = package["author"]
 
-  s.platforms    = { :ios => "10.0", :osx => "10.10" }
+  s.platforms    = { :ios => "11.0", :osx => "10.10" }
   s.source       = { :git => "https://github.com/alpha0010/react-native-file-access.git", :tag => "#{s.version}" }
 
   s.source_files = "ios/**/*.{h,m,mm,swift}"
 
   s.dependency "React-Core"
-  s.dependency "ZIPFoundation", "< 0.9.12"
+  s.dependency "ZIPFoundation", "0.9.11"
 end

This issue body was partially generated by patch-package.

Add a "copyFileRes" function

can you please add this feature?

copyFileRes(filename: string, destPath: string): Promise
Copies the file named filename in the Android app's res folder and copies it to the given destPath path. res/drawable is used as the source parent folder for image files, res/raw for everything else.

i really need to use it with scoped storage :)

Open copied file on external app

Feature
Is there a way to get (dir: 'audio' | 'downloads' | 'images' | 'video') path?

Motivation
I need to move the file to images path, then open this image. If possible add an uri response from cpExternal, or expose this as a Directory constants.

Crypto-js not working with writeFile?

I am trying to use AES encryption with a text, decryption the text is ok but I got an error when trying to write text to file.

let encryptedAES = CryptoJS.AES.encrypt("Message", "My Secret Passphrase").toString();

I pass encryptedAES to writeFile but it fails.
Any help?

Question: How do we read external storage

I'm not seeing a read external storage directory command. Does one exist?

Thanks!

Update:

Upon playing around with the paths it looks like /storage/ is the root folder that contains the externalSD and internal sd.

How to read a uri "content://"

I am using react-native-document-picker and did not know how to 'read' the file? expo-file-system supports SAF URI (A SAF URI is a URI that is compatible with the Storage Access Framework.)

Write pdf file

Hello, i'm using your module to write a pdf on file. I use axios to call API and your module to write the file.
The problem is the final file is incomplete.. it is only 67byte instead the 87kb.
If i open the pdf with a text editor i see that only few rows are written.

is there a fix or i wrong something?

Failed to rename file

Hi,

After downloading a file using react-native-bolb-courier, I'm trying to move it to another location using FileSystem.mv.
While this works fine on Android, I get this error on iOS:

Failed to rename 
'file:///var/mobile/Containers/Data/Application/DFE4D5A0-490C-49B7-A6CF-C8AAB56B8D7F/Library/Caches/83.svg' 
to 
'file:///var/mobile/Containers/Data/Application/DFE4D5A0-490C-49B7-A6CF-C8AAB56B8D7F/Library/Caches/test.svg'

Any ideas how why I can't do it on iOS ? Is it a missing configuration / right ?

Thanks !

react-native-file-access: 1.7.0

Fatal error: Unexpectedly found nil while unwrapping an Optional value

react-native: 0.70.6
react-native-file-access: 2.5.0
Platform: iOS

Bug
A clear and concise description of what the bug is.

To reproduce
Describe how to trigger this bug.

Details
Logs, code snippets, screenshots, extended bug description.

when i writeFile with base64 to png, i got this error.

image

Reading blob data

Bug report

Great work on this library. I am trying to download a pdf from a remote server and store it to external storage on the device. The gist of what I am trying to do is this

Attempt 1: Read file

import {FileSystem} from 'react-native-file-access';

async function getPdf(url: string, options: Object) {
  const res = await fetch(url, options);
  const data = await res.blob();
  const blobPath = URL.createObjectURL(data);
  const data = await FileSystem.readFile(blobPath);  // <--- Error occurs here
  await FileSystem.writeFile('storage/emulated/0/', data);
}

It seems that the readFile function can't find the path of the blob. I have attempted doing the same operation with react-native-fs, and I manage to read blobs there and write them successfully to external storage when they are <~60kB. The error caugth looks like this

[Error: content:/com.app.package.blobs/0db867f8-689d-4e9b-ac73-10185eb9a56d?offset=0&size=51866 (No such file or directory)]

Attempt 2: Copy file

I have also attempted the following

import {FileSystem} from 'react-native-file-access';

async function getPdf(url: string, options: Object) {
  const res = await fetch(url, options);
  const data = await res.blob();
  const blobPath = URL.createObjectURL(data);
  await FileSystem.cpExternal(blobPath, 'name.pdf', 'downloads');
}

Same error ๐Ÿ‘Ž

Env

  • Android: API level 27.
  • WRITE_EXTERNAL_STORAGE is set
  • React Native 0.63.3

[Q] Fetch

Thanks for the library. I just found it today. I have few questions.

  • Does fetch support background downloads?
  • Is it possible to add pause/resume?
  • Any possibility to add support for download progress?

Add installation guides

Feature
Installation Guide

Motivation
Definitely, these kinds of libraries were written by brown-field of RN, so it would be better to add some guides like pod install and manual linking for projects with legacy versions.

Details

  • Auto-linking
  • iOS: manual linking
  • Android: manual linking

how to can i read a dir content

Hello, thanks for the lib, i was wondering if it's possible to list the content of the a dir, i saw FileSystem.readDir but it seems like is just for files. Thanks

written file does not show up and many files not shown with FileSystem.ls

Written files that I write to download are not showing up.

File extensions missing are[apk, txt,bak,pdf,docx]

Are there file extensions that are ignored? Is there a permission I am missing?

Example

const downloadPath =`${Dirs.SDCardDir}/Download`
const output = await FileSystem.ls(`${Dirs.SDCardDir}/Download`)

Updating image file only works after app reboot

I'm trying to updating or deleting an image dynamically based on user preferences, but the name must be the same. So, if I try ti use unlink, for exsample, to delete the image, the Image component keeps displaying it till I close and reopen the app. Same if I change the image but keep the name. Is there a way to make it work? Even updating the states doesn't work

EACCES Permission denied

  • I use android 10, when i want to readFile on android 10 i get error
    " Error: /storage/emulated/0/Download/DB552535-81AF-4B9E-9A17-416F16C30649.png: open failed: EACCES (Permission denied)"
  • My code below:
    const exportedFileContent = await FileSystem.readFile(Dirs.CacheDir + path, 'base64');
    Have any solution?

[0.63.4] - Error building Android debug version

I've installed the 1.7.1 version and when building, this errors appears:

e: /Users/samuelpetroline/Desktop/xxxx/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (40, 32): Expecting an argument
e: /Users/samuelpetroline/Desktop/xxxx/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (325, 71): Expecting an argument
e: /Users/samuelpetroline/Desktop/xxxx/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/FileAccessModule.kt: (306, 30): Unresolved reference: decodeToString

I'm using kotlin_version = '1.3.50'

undefined is not an object

I'm learning react-native in practice and I'm just trying to get the directorof my phone, but you have this error: TypeError: undefined is not an object (evaluating '_$$_REQUIRE(_dependencyMap[0], "react-native-file-access").Dirs.DocumentDir')

[0.65.x] Android build fails, probably incompatibility with okHttp4

probably incompatibility with okHttp4 introduced in 0.65, here and here

After upgrading to react native 0.65.1 Android build returns:

e: /Users/stathis/WebstormProjects/xxxxxx/app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (49, 33): Using 'body(): ResponseBody?' is an error. moved to val
e: /Users/stathis/WebstormProjects/xxxxxx/app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (52, 36): Using 'headers(): Headers' is an error. moved to val
e: /Users/stathis/WebstormProjects/xxxxxx/app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (61, 40): Using 'code(): Int' is an error. moved to val
e: /Users/stathis/WebstormProjects/xxxxxx/app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (62, 44): Using 'message(): String' is an error. moved to val
e: /Users/stathis/WebstormProjects/xxxxxxx/app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (63, 45): Using 'url(): HttpUrl' is an error. moved to val
e: /Users/stathis/WebstormProjects/xxxxxx/app/node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (107, 26): Using 'body(): ResponseBody?' is an error. moved to val

build.gradle

buildscript {
    ext {
        buildToolsVersion = "30.0.2"
        minSdkVersion = 21
        compileSdkVersion = 30
        targetSdkVersion = 30
        supportLibVersion = "29.0.0"
        kotlinVersion = "1.5.21"
        ndkVersion = "20.1.5948944"
    }
    repositories {
       google()
       jcenter()
       mavenCentral()
       }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.1'
        classpath 'com.google.gms:google-services:4.3.8'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
        classpath "com.bugsnag:bugsnag-android-gradle-plugin:5.+"
    }
}

allprojects {
     repositories {
         jcenter()
         mavenCentral()
         mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
      google()
    }
    subprojects {
        project.configurations.all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.android.support'
                        && !details.requested.name.contains('multidex') ) {
                    details.useVersion "29.0.0"
                }
            }
        }
        afterEvaluate {
            project -> if (project.hasProperty("android") || project.plugins.hasPlugin('android-library')) {
                android {
                    compileSdkVersion rootProject.ext.compileSdkVersion
                    buildToolsVersion rootProject.ext.buildToolsVersion
                }
            }
        }
    }
}

Can this library write/upload media file like image, video?

Hello!

I want to implement that user's local file or fetched file upload to application's local storage like android's scoped storage.

But I don't know well about upload to local storage.

I understand this library's documentation explanation like this library can only upload .txt file.

I want to know my understanding is right.

Can I upload media file to local storage like image, video file?

Thank you!

How to ask permission for specific folder

I installed one app from playstore and it downloads the whatsapp stories (basically fetches the . statuses folder from internal storage)

When I installed that app, It directly opened WhatsApp/. statuses folder to ask permission for that specific folder

As per new android 11 policy now no app can get third party folder access it need the access from file manager.

I want to ask if there is any method I can ask permission for specific folder. Like WhatsApp or any other folder ?

Error: Stream Closed [Android]

Hi, I'm using Android 10 and Xiaomi Note 8

using this snippet throws Stream Closed error:

FileSystem.fetch(imageUrl, {
            path: Dirs.CacheDir + `/image.jpg`
          })
            .then(() => {
              return FileSystem.stat(Dirs.CacheDir + `/image.jpg`).then((stat) => {
                return FileSystem.exists(stat.path).then((e) => {
                  if (e) {
                    return FileSystem.cpExternal(
                      stat.path,
                      "savedImage.jpg",
                      "images"
                    ).catch((er) => console.log(er));
                  }
                });
              });
            })
            .catch((e) => console.log(e.message);

build.gradle:

buildscript {
    ext {
        buildToolsVersion = "29.0.2"
        minSdkVersion = 21
        compileSdkVersion = 29
        targetSdkVersion = 29
        supportLibVersion = "29.0.0"
        googlePlayServicesVisionVersion = "19.0.0"
    }

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.BLABLA">

    <queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
        <intent>
            <action android:name="android.intent.action.GET_CONTENT" />
            <data android:mimeType="image/*" />
        </intent>
        <intent>
            <action android:name="android.intent.action.PICK" />
            <data android:mimeType="image/*" />
        </intent>
        <intent>
            <action android:name="android.intent.action.CHOOSER" />
        </intent>
    </queries>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:theme="@style/AppTheme"
        android:requestLegacyExternalStorage="true"
        tools:ignore="GoogleAppIndexingWarning">
        <activity
            android:name=".MainActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
            android:launchMode="singleTask"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:exported="true"
            android:windowSoftInputMode="adjustResize"/>
        <activity
            android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
            android:theme="@style/BootTheme"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
            </intent-filter>
        </activity>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id" />
    </application>

</manifest>

Image downloading works, the image is stored in app's cache dir and it has full size on disk (not 0 bytes).

Image is being copied to DCIM/Pictures but the size is 0 bytes.

Logcat logs shows only this error, nothing else.

exact Android version: 10 QKQ1.200114.002

Get base64 from external image

Is it possible to get the base64 data from an external image ?

Actually, I have this code :
await FileSystem.fetch(props.currentMessage.image, {path: Dirs.CacheDir + '/image.jpg'});

is it possible to get the base64 data from the cache path ? (Dirs.CacheDir + '/image.jpg')

Thanks

feat: Custom external directory

Have you considered adding to cpExternal the possibility to copy to a custom directory? E.g. to copy a file not to Downloads, but to My-Awesome-name.

cpExternal has an error: 'int java.lang.String.lastIndexOf(int)' on a null object reference

Environment: pre android Q (API 29) ONLY.

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.lastIndexOf(int)' on a null object reference
    at android.os.Parcel.createException(Parcel.java:1972)
    at android.os.Parcel.readException(Parcel.java:1934)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
    at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
    at android.content.ContentResolver.insert(ContentResolver.java:1594)
    at com.alpha0010.fs.FileAccessModule.cpExternal(FileAccessModule.kt:132)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
    at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
    at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
    at android.os.Looper.loop(Looper.java:214)
    at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:226)
    at java.lang.Thread.run(Thread.java:764)

How to move files to phone storage

Nice library, I noticed that Dirs only points to the apps storage on android and not the phone storage. Is there a way to move/copy files from the cache to the phone storage? or is this a bug?

Can't see file downloaded in ios files app

I use this ->
await FileSystem.cpExternal(`${Dirs.CacheDir}/private_key_${fileName}.txt`, `app_${fileName}.txt`,'downloads')
to download file in android and this -> await FileSystem.writeFile(`${Dirs.DocumentDir}/app_${fileName}.txt`, pk); to download in ios. Its says successful in both the cases. I can check the downloads directory in android and the file is indeed there but incase of ios I cannot see the file in files app. I have already enabled UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace in the Info.plist file. Tried using FileSystem.cp as well and also FileSystem.cpExternal for ios but no luck getting the file in files app. Am I missing something or we can't see the file in the files app at all?

How to list all files in the download or document Dir

Hello thanks for the lib, i am having a couple to worries regarding the implementation of the API's.
My first worry is where the Dirs.DocumentDir actually saves the files, cause am saving my files there but when i try to read i can't find them (when i open my filemanger i can't find them). My second worry was how to read the content of the download, Aussiming i download a file and i used FileSystem.cpExternal to copy it to the download folder, is it possible to list the content of the download folder?. thanks sorry if it's too much ^^!

How to copy files from internal storage into scoped storage in an external SD card in the Podcasts directory?

react-native: 0.66.1
react-native-file-access: 2.4.3
Platform: Android 11

Bug
I can't seem to copy files from the local device storage into permission-based scoped storage on an SD card.

I'm trying to save to the Podcasts directory, but I've tried many directories on the SD card and get the same failing result.

Details

@alpha0010 sorry as this question involves an additional library (react-native-scoped-storage), and I'm not sure if the problem is some incompatibility between the two. I'm wondering if you could see some obvious mistake I'm making with my process...

I'm trying to copy to the scoped storage "Podcasts" directory on an SD card, but I get an error like follows:

Error: /tree/01F6-AC3F:Podcasts/document/01F6-AC3F:Podcasts/7kJmAzNQ3.mp3: open failed: ENOENT (No such file or directory)

Here's the sequence of steps I'm doing to get there...

First, I requested permission to the SD card Podcasts directory using:

import * as ScopedStorage from 'react-native-scoped-storage'
...
  _setExtDownloadFileLocationAndroid10 = async () => {
    const dir = await ScopedStorage.openDocumentTree(true)

    if (dir?.uri?.endsWith('%3APodcasts')) {
      const sdCardDownloadLocation = dir.uri
      await AsyncStorage.setItem(PV.Keys.EXT_STORAGE_DLOAD_LOCATION, sdCardDownloadLocation)  
      ...
    }
  ...
}

Then, on file download using react-native-background-downloader, I download to origDestination (RNFS.TemporaryDirectoryPath), then try to move it into scoped storage:

  const folderPath = RNFS.TemporaryDirectoryPath
  const origDestination = `${folderPath}/${episode.id}${ext}`
  // download the episode from origDestination using react-native-background-downloader
  ...
  // then in the `done` callback, I try to move the file into scoped storage:
  const sdDestination = `${sdCardDownloadLocation}/${episode.id}.mp3`
  await FileSystem.cp(origDestination, sdDestination)
...

However...when I do that I get:

Error: /tree/01F6-AC3F:Podcasts/document/01F6-AC3F:Podcasts/7kJmAzNQ3.mp3: open failed: ENOENT (No such file or directory)

When I use RNFS.TemporaryDirectoryPath or RNFS.DocumentDirectoryPath, I have not been able to find where the file is initially stored by react-native-background-downloader (I might just not know where to look). I have used the Files explorer on the device, and I have used Android File Transfer on my Mac to try to find the files...I also have "show hidden files" enabled and still can't find them.

However, when I use RNFS.DownloadDirectoryPath, I can find the files are successfully downloaded to Internal Storage > Download directory.

In any case, wherever the files are initially downloaded...it seems like according to the error message that react-native-file-access just can't find or write to the SD Card > Podcasts directory.

There must be something fundamental I'm missing about this process...does that make sense, and do you have any advice on how to accomplish this?

JVM 1.6 target?

For whatever reason, the build tools seem to think this library on Android targets JVM 1.6. Here's the error message:

.../node_modules/react-native-file-access/android/src/main/java/com/alpha0010/fs/NetworkHandler.kt: (106, 8): Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option

I've gradle cleaned it out and rebuilt it but still get this. Any ideas?

iOS: pod install throws error: 'react-native-file-access' does not specify a Swift version

react-native v0.61.5
react-native-file-access v1.7.1

My react native project successfully installs all the dependencies during pod install, but in the end throws an error for react-native-file-access saying:

'react-native-file-access' does not specify a Swift version and none of the targets ('ProjectName') integrating it has the 'SWIFT_VERSION' attribute set. Please contact the author or set the 'SWIFT_VERSION' in at least one of the targets that integrate this pod.

Am I missing some configuration in the Build Settings?

readFile() freezes for some seconds when reading small files

Hi, is it normal that when i read a 2MB pdf through readFile() function with base64 encoding, the app freezes for some second?Perceived time would me much less if i could use a spinner while the file is being read, since readFile is async, but it doesn't work :(

stat and deleteFile say file does not exist for files in scoped storage in an SD card

react-native: 0.66.1
react-native-file-access: 2.4.4
Platform: Android 11

Bug
I can't seem to delete files from scoped storage on an external SD card.

I'm trying to delete a file in scoped storage with:

await FileSystem.unlink('content://com.android.externalstorage.documents/tree/01F6-AC3F%3APodverse/document/01F6-AC3F%3APodverse/D9_Zc6_nz.mp3')

But I get the error message:

Error: 'content://com.android.externalstorage.documents/tree/01F6-AC3F%3APodverse/document/01F6-AC3F%3APodverse/D9_Zc6_nz.mp3' does not exist.

I get the same error message when I call:

await FileSystem.stat('content://com.android.externalstorage.documents/tree/01F6-AC3F%3APodverse/document/01F6-AC3F%3APodverse/D9_Zc6_nz.mp3')

@alpha0010 just fixed a different issue with calling await FileSystem.cp(...) with SD card scoped storage. Could there be corresponding fixes needed for stat and deleteFile?

I have also tried deleting these files with react-native-fs and react-native-scoped-storage. react-native-fs failed to delete the file because of an access issue. react-native-scoped-storage has a different bug where it deletes the whole directory instead of the file specified ๐Ÿคฆโ€โ™‚๏ธ

FileSystem.fetch Error: Expected URL scheme

When fetching to file on Android (did not try iOS yet), the call always fails with the error:

Error: Expected URL scheme 'http' or 'https' but no colon was found

This is the code that I am using:

import { Dimensions } from "react-native";
import { Dirs, FileSystem } from "react-native-file-access";
import "react-native-get-random-values"; // make sure to import before "uuid";
import * as uuid from "uuid";

const SCREEN_WIDTH = Dimensions.get("screen").width;

function download(url, accessToken){
    // url = "https://my.website.com/uploaded/12345"

    const headers = { Cookie: `token=${accessToken}` };
    const method = "GET";
    const path = `${url}?max_width=${SCREEN_WIDTH}`;
    const localFilePath = `${Dirs.CacheDir}/${uuid.v4()}.cache`;
    
    return FileSystem.fetch(localFilePath, { headers, method, path }).then((result) => {
        if (result.ok === false){ return Promise.reject(result); }
        return Promise.resolve(localFilePath);
    });
}

Can you please let me know what is wrong in the call above?
I tried adding scheme: "https" to the init object, received the same error

Environment
[email protected] | MacOS BigSur (Intel) | expo bare workflow (SDK43) | react-native 0.64.3 | [email protected] | Android Studio 2020.3.1

cpExternal to 'downloads' works in Android but not in iOS

Hello,

While it works in iOS, the cpExternal does not work in iOS. Note that I have both UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace enabled. Testing in emulator. Shouldn't the destination ('downloads') be a "common" folder and not an application-specific folder?

Is this a bug or a non-proper implementation?

Thanks a lot!

image

const fetchPayment = async (paymentId, createdDate) => {
  const token = await getAuthToken();
  console.log('token', token);

  const destPath = `${Dirs.CacheDir}/${createdDate}-Invoice.pdf`;

  // const date = new Date();
  const { data } = await new Promise((resolve, reject) => {
    try {
      FileSystem.fetch(
        `${window.our.BASE_URL}/payment?paymentId=${paymentId}`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
            Accept: 'application/pdf',
            'Content-Type': 'application/pdf',
          },
          path: destPath,
        },
      )
        .then(async res => {
          console.log('res', res);
          await FileSystem.cpExternal(
            destPath,
            `${createdDate}-Invoice.pdf`,
            'downloads',
          );
          Alert.alert(
            t('invoiceDownloaded'),
            t('invoiceDownloadedAndroidFolder'),
          );
          resolve(res);
        })
        // Something went wrong:
        .catch((errorMessage, statusCode) => {
          console.log(errorMessage);
          reject(errorMessage);
        });
    } catch (err) {
      console.log(err);
      reject(err);
    }
  });
  return data;
};

fix writeFile base64string failed

Hi! ๐Ÿ‘‹

Firstly, thanks for your work on this project! ๐Ÿ™‚

Today I used patch-package to patch [email protected] for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-file-access/ios/FileAccess.swift b/node_modules/react-native-file-access/ios/FileAccess.swift
index 894a8fe..623da20 100644
--- a/node_modules/react-native-file-access/ios/FileAccess.swift
+++ b/node_modules/react-native-file-access/ios/FileAccess.swift
@@ -329,7 +329,7 @@ class FileAccess: RCTEventEmitter {
             do {
                 if encoding == "base64" {
                     let pathUrl = URL(fileURLWithPath: path.path())
-                    guard let decoded = Data(base64Encoded: data) else {
+                    guard let decoded = Data(base64Encoded: data, options: .ignoreUnknownCharacters) else {
                         reject("ERR", "Failed to write to '\(path)', invalid base64.", nil)
                         return
                     }

This issue body was partially generated by patch-package.

Support for new react native architecture

Feature
Support for the new react native architecture

Motivation
A lot of libraries use this library internally (e.g. react-native-image-cache). Making sure this library supports new architecture can be helpful for a lot of other library

[feature-request] Adding album field to cpExternal

When i use cpExternal to save images in my app, it saves the images to root of the Pictures directory. Can an album field be added to cpExternal function like below?

FileSystem.cpExternal(sourceUri, 'my-picture', 'my-album', 'images')

So it will save the images to Pictures/my-album/ directory or can the uri of the Pictures directory exposed via Dirs. so we can use mkdir and cp to copy the image into necessary folder.

Thanks!

Error on basic use

Hello,

I'm trying to integrate this repo into my app, but can't make it work even on basic instruction of the readme
const text = await FileSystem.readFile(Dirs.CacheDir + '/test.txt'); nor on a simple console.log(Dirs.CacheDir) after importing as stated : import { Dirs, FileSystem } from 'react-native-file-access';.

I get the following error :
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_reactNativeFileAccess.Dirs.CacheDir')]

Guess there must be something wrong in my configuration ? Developping on Windows using npm and expo-cli (4.12.0).
Using react-native v0.63.4 hence set react-native-file-access to v1.7.1 as required by the readme.

App and package.zip

Thanks for your help

react-native-file-access:compileDebugKotlin

I get this error. when trying to run react-native run-android and the same with yarn android

  • What went wrong:
    Execution failed for task ':react-native-file-access:compileDebugKotlin'.

Compilation error. See log for more details

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 1m 21s

Tried googling the error and tried the solutions and it seems to be related to the module

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.