React Native Android中RNFetchBlob.fs.dirs未定义问题求助
问题:rn-fetch-blob中
RNFetchBlob.fs.dirs未定义导致应用更新失败 问题详情
应用内下载APK进行自动更新时,抛出错误:
TypeError: undefined is not an object (evaluating 'RNFetchBlob.fs.dirs')
已尝试的链接方式均无效:
- 执行
react-native link rn-fetch-blob自动链接原生模块 - 按照文档手动链接原生模块
使用版本:
react-native": "0.68.2"rn-fetch-blob": "^0.12.0"
相关代码
React Native 代码
import React, { memo } from 'react'; import { Button, View } from 'react-native'; import { NativeModules } from 'react-native'; const RNFetchBlob = NativeModules.RNFetchBlob; const Startnow = memo(({ navigation }) => { const updateApp = () => { console.log("App Update") const android = RNFetchBlob.android; RNFetchBlob.config({ addAndroidDownloads: { useDownloadManager: true, title: 'stocksy.apk', description: 'An APK that will be installed', mime: 'application/vnd.android.package-archive', mediaScannable: true, notification: true, path: RNFetchBlob.fs.dirs.DownloadDir + '/stocksy.apk', // 报错位置 }, }) .fetch( 'GET', 'https://kickstart-public.s3.ap-south-1.amazonaws.com/app/stocksy.apk', ) .then(res => { console.log("==================Res==============", res) android.actionViewIntent( res.path(), 'application/vnd.android.package-archive', ); }); }; return ( <View style={styles.descrip}> <Button onPress={updateApp} title="Update App" color="#841584" /> </View> ) })
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.stocksy"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 控制前台通知弹窗显示 --> <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="false"/> <!-- 设置通知颜色 --> <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/white"/> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" android:exported="false"/> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" android:exported="false"/> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> </intent-filter> </receiver> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" > <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> </application> </manifest>
settings.gradle
rootProject.name = 'Stocksy' apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' include ':rn-fetch-blob' project(':rn-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/rn-fetch-blob/android') includeBuild('../node_modules/react-native-gradle-plugin') if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { include(":ReactAndroid") project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') } include ':react-native-razorpay' project(':react-native-razorpay').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-razorpay/android') include ':react-native-push-notification' project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/android') include ':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
解决方案
1. 修正RNFetchBlob导入方式
当前通过NativeModules导入的方式错误,rn-fetch-blob的JS层封装了fs、android等API,正确导入方式为:
import RNFetchBlob from 'rn-fetch-blob';
替换原来的import {NativeModules} from 'react-native'; const RNFetchBlob = NativeModules.RNFetchBlob;。
2. 添加Android 10+兼容配置
在AndroidManifest.xml的<application>标签中添加android:requestLegacyExternalStorage="true",解决分区存储限制:
<application ... android:requestLegacyExternalStorage="true" ...>
3. 检查手动链接完整性
确认android/app/build.gradle的dependencies块中添加了依赖:
implementation project(':rn-fetch-blob')
同时在MainApplication.java中注册模块:
import com.RNFetchBlob.RNFetchBlobPackage; @Override protected List<ReactPackage> getPackages() { List<ReactPackage> packages = new PackageList(this).getPackages(); packages.add(new RNFetchBlobPackage()); return packages; }
4. 清理缓存重新构建
执行以下命令清除缓存,避免构建残留问题:
npm cache clean --force cd android && ./gradlew clean cd .. && npm install npx react-native run-android
内容的提问来源于stack exchange,提问作者Avinash A
相关产品推荐
相关产品推荐

