react-native-blob-util

repository·master·Indexed 21 days ago

https://github.com/ronradtke/react-native-blob-util

A React Native library providing upload, download, and file access APIs. It features customizable filesystem and network modules that support direct data transfer to/from storage to avoid BASE64 bridging overhead. The module includes support for file stream read/write for large files, Android Download Manager integration, Android Media Store management via MediaCollection API, and multipart/form-data uploads.

Tokens
7.8K
Snippets
24
Records
31
Agent score
76%

What's inside react-native-blob-util

  1. Important caveats and usage notes

    master

    Keep the following behaviors in mind when using react-native-blob-util:

    • URL Encoding: The library does not automatically urlencode unicode characters in URLs.
    • Blob Lifecycle: If you create a Blob from an existing file, that file WILL BE REMOVED if you call close on the blob.
    • XMLHttpRequest replacement: Replacing window.XMLHttpRequest (e.g., to support Firebase SDK) will also affect the official fetch implementation.
    • Progress Event Overhead: If file stream or upload/download progress events slow down your app, upgrade to 0.9.6+ and use additional arguments to limit event frequency.
    • File Paths: When passing a file path to the library, you must remove the file:// prefix.
  2. Optimize performance for data transfer and encoding

    master

    To improve app performance when handling large data, follow these best practices:

    • Avoid BASE64: Passing large BASE64 strings over the React Native bridge incurs significant overhead. Use file storage instead of BASE64 whenever possible.
    • Avoid ASCII Encoding: Converting data to JS byte arrays via ASCII encoding is extremely slow due to limitations in JavaScriptCore. Use it only when strictly necessary.
    • Use 'uri' encoding for file operations: When concatenating or replacing files, use the uri encoding for writeFile and appendFile APIs. This allows the process to be handled entirely in native code without reading data into the JS context.
  3. Use Web API Polyfills for Blob and XMLHttpRequest

    master

    The library provides experimental Web API polyfills to make browser-based libraries available in React Native. These include:

    • Blob
    • XMLHttpRequest (It is recommended to use the library's implementation if you are using it in conjunction with Blob).
  4. How HTTP request bodies are handled

    master

    Since version 0.8.0, react-native-blob-util automatically determines how to send the request body based on the type and the Content-Type header:

    • Form Data: The Content-Type header is ignored. If the body is an Array, the library sets the proper content type for you.
    • Binary Data: You can use a BASE64 encoded string or a file path.
      • If Content-Type contains ;BASE64 or application/octet, the body is treated as BASE64 and decoded to binary.
      • Otherwise, if the string starts with ReactNativeBlobUtil-file:// (use ReactNativeBlobUtil.wrap(PATH) to generate this), it uses the file at that URI as the body.
    • As-is: To send the body without transformation, use a Content-Type that does not contain ;BASE64 or application/octet.

    Important Notes:

    • Caching: HTTP requests use cache by default. To disable it, add the header 'Cache-Control': 'no-store'.
    • Chunked Encoding: Chunked transfer encoding is disabled by default since 0.9.4. To use it, explicitly set the Transfer-Encoding header to Chunked.
  5. Import react-native-blob-util in your project

    master

    The module uses ES6 exports. If you are using ES5 require, you must append .default to the import statement.

    // ES6 usage
    import ReactNativeBlobUtil from 'react-native-blob-util'
    // ES5 usage
    var ReactNativeBlobUtil = require('react-native-blob-util').default
  6. Configure Android permissions for external storage

    master

    For Android 5.0 or lower, you must manually add permissions to your AndroidManifest.xml to access external storage.

    To automatically add Android permissions during linking (for projects using react-native link), use the RNFB_ANDROID_PERMISSIONS=true environment variable.

    ```sh
    # Automatically add permissions during linking
    RNFB_ANDROID_PERMISSIONS=true react-native react-native-blob-util

    Manual Manifest additions for Android 5.0 or lower:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />

    Additional requirements:

    • Android Download Manager: Add <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/> to your intent filter.
    • wifiOnly flag: Add <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />.
  7. Use Android Download Manager for large files

    master

    For large downloads on Android, use the system DownloadManager. This provides native progress bars and notifications and handles the task via the OS.

    Requirements & Limitations:

    • Requires useDownloadManager: true in the addAndroidDownloads config.
    • Only supports the GET method (request body is ignored).
    • fileCache and path in the top-level config() are ignored because DownloadManager stores files in external storage.
    • You must specify a path in addAndroidDownloads to avoid permission/parsing issues when installing APKs.
    ReactNativeBlobUtil
            .config({
                addAndroidDownloads: {
                    useDownloadManager: true,
                    notification: true,
                    title: 'Download Success',
                    description: 'An image file.',
                    mime: 'image/png',
                    mediaScannable: true,
                }
            })
            .fetch('GET', 'http://example.com/file/somefile')
            .then((resp) => {
                console.log('Downloaded to:', resp.path())
            })
  8. Manage cached files and sessions

    master

    When using fileCache: true or the path option with fetch, files are stored in the file system and are not automatically removed. You must manage them manually to prevent storage bloat.

    Removal Methods

    1. res.flush(): Call this on a ReactNativeBlobUtilResponse object to remove the specific cached file associated with that response.
    2. fs.unlink(path): Remove a file by its specific path.
    3. session.dispose(): Group multiple requests into a session and remove all files in that session at once.

    Using Sessions

    You can assign a response to a session using res.session('name') or configure a session globally in .config({ session: 'name' }). You can also manually manage sessions via ReactNativeBlobUtil.session('name') to add, remove, or list file paths.

    // Using sessions to group and dispose of files
    ReactNativeBlobUtil.config({ session: 'my-session', fileCache: true })
        .fetch('GET', 'http://example.com/file')
        .then((res) => {
            // Files are now part of 'my-session'
        });
    
    // Later, clear all files in that session
    ReactNativeBlobUtil.session('my-session').dispose().then(() => {
        console.log('Session cleared');
    });
  9. Install react-native-blob-util via npm or CocoaPods

    master

    To install the package using npm, run the install command. For iOS projects, you must also add the pod to your Podfile and run pod install from the ios directory.

    npm install --save react-native-blob-util
    # For iOS
    cd ios; pod install; cd ..
  10. Upload files using Multipart/form-data

    master

    To post form data containing both text and files, pass an Array as the body in fetch(). Each element in the array is an object with the following properties:

    • name: The field name.
    • data: The value (string, BASE64, or a wrapped file path).
    • filename (optional): If present, the element is treated as a file. If absent, it is sent as a UTF-8 string.
    • type (optional): Custom MIME type (e.g., 'image/png').

    To upload a file from storage within a multipart request, wrap the path using ReactNativeBlobUtil.wrap(PATH).

    ReactNativeBlobUtil.fetch('POST', 'http://www.example.com/upload-form', {
        'Content-Type': 'multipart/form-data',
    }, [
        // File from BASE64
        {name: 'avatar', filename: 'avatar.png', data: binaryDataInBase64},
        // File from storage
        {name: 'avatar-foo', filename: 'avatar-foo.png', type: 'image/foo', data: ReactNativeBlobUtil.wrap(path_to_a_file)},
        // Plain text field
        {name: 'name', data: 'user'},
        // JSON field
        { name: 'info', data: JSON.stringify({ mail: 'test@example.com' }) }
    ]).then((resp) => {
        // ...
    });
  11. Implement and set a File Transformer

    master

    You can specify how data is transformed whenever the library reads from or writes to storage (e.g., for encryption). To use a file transformer, you must implement the platform-specific interface:

    • iOS: ReactNativeBlobUtilFileTransformer.h
    • Android: ReactNativeBlobUtilFileTransformer.java

    Once implemented, set the transformer during app startup.

    The transformer applies to:

    • Reading a file from the file system.
    • Writing a file into the file system.
    • HTTP responses downloaded directly to storage.
    // Android: Set in MainApplication.java
    public class MainApplication extends Application implements ReactApplication {
        @Override
        public void onCreate() {
           ReactNativeBlobUtilFileTransformer.sharedFileTransformer = new MyCustomEncryptor();
        }
    }
    
    // iOS: Set in AppDelegate.m
    @implementation AppDelegate
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        [ReactNativeBlobUtilFileTransformer setFileTransformer: MyCustomEncryptor.new];
        return YES;
    }
  12. Download files directly to storage

    master

    For large files, stream the response directly to a file to avoid memory issues. Use the fileCache: true option in config(). By default, these files are stored in a temporary path without a file extension.

    Note: These files are not removed automatically; you must manage them manually.

    ReactNativeBlobUtil
            .config({
                // add this option that makes response data to be stored as a file,
                // this is much more performant.
                fileCache: true,
            })
            .fetch('GET', 'http://www.example.com/file/example.zip', {
                //some headers ..
            })
            .then((res) => {
                // the temp file path
                console.log('The file saved to ', res.path())
            })