react-native-blob-util icon indicating copy to clipboard operation
react-native-blob-util copied to clipboard

[Android] TypeError: null is not an object (evaluating '_NativeBlobUtils.default.getConstants')

Open owencraston opened this issue 1 year ago • 10 comments

Issue

I am getting the following error when trying to build on Android API 30. This is not an EXPO project. I am not getting this issue at all on iOS and it builds perfectly with xcode.

Error:

 ERROR  TypeError: null is not an object (evaluating '_NativeBlobUtils.default.getConstants')
 ERROR  Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
 ERROR  Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
      This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.

Context

here is my React native info:

System:
    OS: macOS 13.2.1
    CPU: (10) x64 Apple M1 Pro
    Memory: 24.57 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 14.21.3 - ~/.nvm/versions/node/v14.21.3/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v14.21.3/bin/yarn
    npm: 6.14.18 - ~/.nvm/versions/node/v14.21.3/bin/npm
    Watchman: 2023.03.20.00 - /opt/homebrew/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /Users/owencraston/.rbenv/shims/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1
    Android SDK:
      API Levels: 29, 30, 31, 32
      Build Tools: 30.0.2, 30.0.3, 32.0.0, 32.1.0
      System Images: android-29 | ARM 64 v8a, android-29 | Google APIs ARM 64 v8a, android-30 | Google Play ARM 64 v8a, android-32 | Google APIs ARM 64 v8a
      Android NDK: Not Found
  IDEs:
    Android Studio: 2022.1 AI-221.6008.13.2211.9514443
    Xcode: 14.2/14C18 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.17 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: 0.66.5 => 0.66.5
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
  • please provide the version of installed library and RN project.
  • "react-native-blob-util": "^0.17.2",
    • I am also using "redux-persist-filesystem-storage": "4.1.0",
  • a sample code snippet/repository is very helpful to spotting the problem.
const fetchAndStoreNPMPackage = async (
  inputRequest: RequestInfo,
): Promise<string> => {
  const { config } = ReactNativeBlobUtil;
  const filePath = `${ReactNativeBlobUtil.fs.dirs.DocumentDir}/archive.tgz`;
  const urlToFetch: string =
    typeof inputRequest === 'string' ? inputRequest : inputRequest.url;

  try {
    const response: FetchBlobResponse = await config({
      fileCache: true,
      path: filePath,
    }).fetch('GET', urlToFetch);
    const dataPath = response.data;
    const targetPath = ReactNativeBlobUtil.fs.dirs.DocumentDir;
    try {
      const decompressedPath = await decompressFile(dataPath, targetPath);
      return decompressedPath;
    } catch (error) {
      Logger.log(
        SNAPS_NPM_LOG_TAG,
        'fetchAndStoreNPMPackage failed to parse data with error:',
        error,
      );
      throw new Error(
        `fetchAndStoreNPMPackage failed to parse data with error: ${error}`,
      );
    }
  } catch (error) {
    Logger.log(SNAPS_NPM_LOG_TAG, 'fetchAndStoreNPMPackage error', error);
    throw new Error(`fetchAndStoreNPMPackage error: ${error}`);
  }
};
  • issues which have been tagged as 'needs feedback', will be closed after 2 weeks if receive no feedbacks.
  • https://github.com/RonRadtke/react-native-blob-util/issues/33 I tried everything in this thread and it did not work.

What I tried

  • cleaning watchman cache
  • cleaning build folder and cache
  • wiping simulator data
  • adding permissions to my android manifest
  • invalidating my android studio cache and restarting
  • deleting and reinstalling node modules
  • running pod install in the ios folder

owencraston avatar Mar 27 '23 21:03 owencraston

I was able to fix this by simply removing the library and reverting back to "rn-fetch-blob": "^0.12.0",....so not the best fix but the API is pretty much the same so it will do.

owencraston avatar Mar 27 '23 22:03 owencraston

I'm having the same problem.

I'm currently running it on Android 12 (Samsung Galaxy S10e) within Windows and it's an ejected Expo App.

superjose avatar Apr 05 '23 13:04 superjose

I found the solution!!!!

The problem is that the documentation needs to be updated.

Here's the step by step process

Details:

  • Using Android (iOS is untested) with an ejected Expo 0.46 app.
  • Package version: "react-native-blob-util": "0.17.3"

1st. Add on your app/android/app/build.gradle file:

dependencies {
// other dependencies
  implementation project(':react-native-blob-util')
// other dependencies
}

2nd. In your android/app/src/main/AndroidManifest.xml, verify that you have:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.app.name" xmlns:tools="http://schemas.android.com/tools">
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
    <application ... >
         <activity ...>
               <intent-filter>
                    <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
               </intent-filter>
          </activity>
</manifest>

I am curious to know whether those were valid. I think the most important one is WRITE_EXTERNAL_STORAGE (But that's what I have on my AndroidManifest.xml)

3rd. on your app/android/settings.gradle, add:

include ':react-native-blob-util'                                                                                                  
project(':react-native-blob-util').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-blob-util/android');

Notes:

  • We're not using compile in any of these.
  • We did not add the package to the MainApplication.java file as these were automatically added.

4th. Compile your project (In my case I sent it to Expo).

5th. Import as usual (example):

import { useCallback } from 'react';
import ReactNativeBlobUtil from 'react-native-blob-util';
import share from 'react-native-share';
import { PermissionsAndroid, Platform } from 'react-native';
import { useToast } from '@components/toast/useToast';
import { t } from '@lingui/macro';

type DownloadStatementsInput = {
    url: string;
    filename: string;
};

export function useDownloadStatements(input: DownloadStatementsInput) {
    const { url, filename } = input;
    const displayToast = useToast();
    const bankToken = 'The Bank Token';
    return useCallback(async () => {
        try {
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
                {
                    title: 'storage title',
                    message: 'storage_permission',
                    buttonPositive: 'ok',
                }
            );

            if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
                console.log('Permission denied');
                return;
            }
            const dirs = ReactNativeBlobUtil.fs.dirs;
            displayToast(
                t`Downloading your statement for ${filename}.`,
                'info'
            );

            const result = await ReactNativeBlobUtil.config({
                fileCache: true,
                appendExt: 'pdf',
                path: `${dirs.DownloadDir}/${filename}`,
                addAndroidDownloads: {
                    useDownloadManager: true,
                    notification: true,
                    mediaScannable: true,
                    title: filename,
                    description: `Pana Bank Statement for $`,
                    mime: 'application/pdf',
                },
            }).fetch('GET', url, {
                Authorization: `Bearer ${bankToken}`,
                'x-pana-client-source': 'PANA_APP',
            });

            const androidMessage =
                Platform.OS === 'android'
                    ? t` Open your notifications for the PDF.`
                    : ``;
            displayToast(t`Downloading finished. ${androidMessage}`, 'info');

            // in iOS, we want to save our files by opening up the saveToFiles bottom sheet action.
            // whereas in android, the download manager is handling the download for us.

            if (Platform.OS === 'ios') {
                const filePath = result.path();
                let options = {
                    type: 'application/pdf',
                    url: filePath,
                    saveToFiles: true,
                };
                share
                    .open(options)
                    .then(resp => console.log(resp))
                    .catch(err => console.log(err));
            }
        } catch (e) {}
    }, [bankToken, url, filename]);
}

superjose avatar Apr 05 '23 19:04 superjose

@superjose Thanks for then help. I have tried your solution but am still getting the same error. Here is what I did...

  1. edited dependencies android/app/build.gradle to include
implementation project(':react-native-blob-util')
  1. edited android/settings.gradle to include...
include ':react-native-blob-util'
project(':react-native-blob-util').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-blob-util/android');
  1. added the following to android/app/src/main/AndroidManifest.xml
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  	<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
...

			<intent-filter>
				<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
			</intent-filter>

I didn't change my js code to request permissions but I don't think it would make a difference since I am getting this error when I build the app from android studio.

You can see my entire PR here for more information. We are not using expo so maybe that has something to do with it? I noticed that you mentioned you ejected the app? what does this achieve?

@RonRadtke could we get some help here? this is a major blocker for my project. I tried using rn-fetch-blob (which does not give me this error) but I am encountering another error which requires me to migrate to your package.

owencraston avatar Apr 21 '23 23:04 owencraston

@owencraston did you manage to solve the issue now? I can't reproduce it, might habe to try with your app. The manual liking described for expo should not be needed

RonRadtke avatar May 17 '23 05:05 RonRadtke

Thank you @RonRadtke for responding. I've since migrated back to RNFetchBlob for the time being. That package has its own issues (namely this one) but I was able to get it working on certain version of android. To reproduce I would try doing the following.

  • checkout this commit. (4ffc810ec0b8443f188420aacd04fc5b18a9ec21)
  • go through the environment setup found in the readme here.
  • Make sure you follow the steps here to setup your infura project id
  • Assuming you already have react native setup on your machine you will need to run yarn setup
  • Try to build on Android via android studio (the command line never works for me). I was testing with Android API version 30 on a pixel 3a emulator.
  • You should see the build error.
  • If not and you build successfully.... create a test wallet with a dummy password and skip the account section. Navigate to the drawer view (hamburger menu on the side) and click snaps. Then click install with the value npm:@chainsafe/filsnap' in the text field.

The above branch is old and stale so it may fail for various reasons. If this happens you can always repoduce by doing the following....

  • checkout the branch flask in metamask-mobile. The PR is here.
  • Follow the same setup steps above, install the relevant packages and setup your infura id.
  • Then you can replace all the instances of RNFetchBlob with react-native-blob-util. This includes adding it to the package.json and running yarn install
  • Assuming you already have react native setup on your machine you will need to run yarn setup and run android
  • If you don't see the error then do install the snap the same way as mentioned in the last step above.

I appreciate your help with this. Let me know if you have any questions or if these reproduction steps do not work. I will try and get a more up to date branch ready for you if not. I wonder if this issue stems from our project previously using RNFetchBlob and perhaps not cleaning up the old usage of it.

owencraston avatar May 17 '23 17:05 owencraston

I should also mention that adding the permissions did not solve the problem for me.

owencraston avatar May 17 '23 17:05 owencraston

But just to be on the save side before investing hours... Did you try to delete the node_modules and reinstall all libs, run a react-native start --reset-cache and try then again? Because for me it looks like the module is not loaded correctly. Maybe you can add a log here: https://github.com/RonRadtke/react-native-blob-util/blob/132051c1204051f5148a0b4bfede00ed99f47c44/fs.js#L13 console.log(ReactNativeBlobUtil)

To see if the module is actually correctly loaded or if the error is due to module not being loaded at all

RonRadtke avatar May 18 '23 07:05 RonRadtke

@RonRadtke react-native-blob-util/fs.js

console.log(ReactNativeBlobUtil) is null How to handle it?

286581424 avatar Jul 16 '23 11:07 286581424

I was able to solve the problem with this solution.

my environment:

System:
    OS: macOS 13.4.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 73.29 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 16.20.1 - ~/.nvm/versions/node/v16.20.1/bin/node
    Yarn: 1.22.19 - ~/.yarn/bin/yarn
    npm: 8.19.4 - ~/.nvm/versions/node/v16.20.1/bin/npm
    Watchman: 2023.06.26.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /Users/shunsaku/.rbenv/shims/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.4, iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4
    Android SDK:
      Android NDK: 23.1.7779620
  IDEs:
    Android Studio: 2022.3 AI-223.8836.35.2231.10406996
    Xcode: 14.3.1/14E300c - /usr/bin/xcodebuild
  Languages:
    Java: javac 17 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: ^17.0.2 => 17.0.2 
    react-native: 0.66.5 => 0.66.5 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

other packages:

"react-native-blob-util": "^0.18.3",
"react-native-pdf": "^6.7.0",

synsax avatar Aug 15 '23 11:08 synsax