fix(firebase web sdk): new breaking change
See original GitHub issueSummary
Recently, precisely 7 days ago, Firebase pushed an update to their JavaScript SDK that added a new dependency, idb to their app
package. This new dependency uses a .cjs file as its main entry point, a file extension, which by default, is not bundled with metro. This immediately causes a fatal JS error rendering the application unusable unless the user explicitly adds cjs
as a sourceExt in their metro.config.js:
const { getDefaultConfig } = require('@expo/metro-config');
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.sourceExts.push('cjs');
module.exports = defaultConfig;
This is definitely not something on Expo’s side nor is it an SDK bug, but it is something that would affect the better part of the userbase. And not to mention the amount of users who think this error came from “upgrading to sdk 45”.
Managed or bare workflow? If you have ios/
or android/
directories in your project, the answer is bare!
managed
What platform(s) does this occur on?
Android, iOS, Web
SDK Version (managed workflow only)
all
Environment
expo-env-info 1.0.3 environment info: System: OS: macOS 12.3.1 Shell: 5.8 - /bin/zsh Binaries: Node: 16.14.0 - /usr/local/bin/node Yarn: 1.22.17 - /usr/local/bin/yarn npm: 8.3.1 - /usr/local/bin/npm Watchman: 2022.03.14.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5 Android SDK: API Levels: 30, 32 Build Tools: 29.0.2, 30.0.2, 32.0.0 System Images: android-30 | Wear OS 3 - Preview Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom, android-Tiramisu | Android TV Intel x86 Atom IDEs: Android Studio: 2020.3 AI-203.7717.56.2031.7935034 Xcode: 13.3.1/13E500a - /usr/bin/xcodebuild npmPackages: expo: ~44.0.0 => 44.0.6 react: 17.0.1 => 17.0.1 react-dom: 17.0.2 => 17.0.2 react-native: 0.64.3 => 0.64.3 react-native-web: 0.17.7 => 0.17.7 npmGlobalPackages: eas-cli: 0.52.0 expo-cli: 5.4.3 Expo Workflow: managed
(THIS AFFECTS ALL SDK VERSIONS, BOTH MANAGED AND BARE WORKFLOWS, AND ALL ENVIROMENTS)
Reproducible demo
Package.json:
{
"name": "HelloWorld",
"version": "1.0.0",
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/stack": "^6.2.1",
"expo": "~44.0.0",
"expo-splash-screen": "~0.14.1",
"expo-status-bar": "~1.2.0",
"firebase": "^9.8.1",
"react": "17.0.1",
"react-dom": "17.0.2",
"react-native": "0.64.3",
"react-native-gesture-handler": "~2.1.0",
"react-native-paper": "^4.12.1",
"react-native-reanimated": "~2.3.1",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-web": "0.17.7"
},
"devDependencies": {
"@babel/core": "^7.12.9"
},
"private": true
}
App.js:
...
import { initializeApp } from 'firebase/app'
...
Issue Analytics
- State:
- Created a year ago
- Reactions:12
- Comments:7 (3 by maintainers)
In my case I was running into another problem after using the custom metro config workaround:
When debugging the code, _idb somehow resolves to 9 instead of the actual idb module.
I’ve also posted the issue on firebase-js-sdk: https://github.com/firebase/firebase-js-sdk/issues/6253#issuecomment-1159733409
Another workaround
Metro bundler can actually process the idb/index.js file which is a native ES module. So as another workaround, the package.json file of idb can be modified so that
"main": "index.js"
.In this case the custom metro configuration is not necessary at all.
The change can be persisted by using patch-package and
yarn patch-package idb --exclude 'nothing'
Concerns
I wonder if the problem that I’m having with the .cjs file points to some underlying bug with Metro bundler (or Expo)?
Maybe Metro bundler should actually attempt to resolve the “module” entry point of an npm package instead of “main”?
Thanks for this fix, it solved my problem and I’m now on Firebase 9.8.
A bit more information is that I had been on Firebase 9.1, but when I upgraded to Expo 45, that’s when it failed and began to give error messages. I checked Firebase’s changelog and found that older versions of v9 had the problem, as did version 9.8+, but 9.7.0 was safe. So if somebody doesn’t want to do this metro.config.js thing, they can install Firebase 9.7.0.
However, when I ran expo upgrade again while already on SDK 45, even though my package.json still indicated Firebase 9.7.0, the problem returned. I had to run npm install Firebase 9.7.0 again. So maybe expo upgrade is overwriting something, which causes the failure, then by re-installing Firebase 9.7.0 we overwrite that and get the correct configuration? I don’t know enough about these things yet to know for sure what’s going on.