I am experiencing an issue with Firebase in a React Native Web application bundled with Webpack. The problem arises when I switch to production mode. In development mode, everything works perfectly fine, but when I build for production, I encounter the following error:
DOMException: Failed to execute 'put' on 'IDBObjectStore': The transaction is not active.
This error seems to be related to IndexedDB transactions.
Firebase initialization code:
import {initializeApp} from 'firebase/app';
const firebaseConfig = {
apiKey: '---',
authDomain: '---',
databaseURL: '---',
projectId: '---',
storageBucket: '---',
messagingSenderId: '---',
appId: '---',
measurementId: '---',
};
firebaseApp = initializeApp(firebaseConfig);
firebaseApp.automaticDataCollectionEnabled = true;
Webpack config:
const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const appDirectory = path.resolve(__dirname, '../');
const babelConfig = require(path.resolve(appDirectory, 'babel.config'));
// Babel loader configuration
const babelLoaderConfiguration = {
test: /\.(tsx|jsx|ts|js)?$/,
include: [
path.resolve(appDirectory, '../libs'),
path.resolve(appDirectory, './src'),
path.resolve(appDirectory, './app.json'),
path.resolve(appDirectory, '../node_modules'),
],
exclude: [
path.resolve(
appDirectory,
'../node_modules/@firebase/app/node_modules/idb',
),
path.resolve(appDirectory, '../node_modules/@babel/runtime/helpers'),
path.resolve(appDirectory, '../node_modules/babel-runtime'),
path.resolve(appDirectory, '../node_modules/glob'),
path.resolve(appDirectory, '../node_modules/immer'),
],
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
// Presets and plugins imported from main babel.config.js in root dir
presets: babelConfig.presets,
plugins: ['react-native-web', ...(babelConfig.plugins || [])],
},
},
};
// Image loader configuration
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
esModule: false,
},
},
};
module.exports = (_, argv) => {
return {
target: 'web',
devServer: {
port: 8080,
static: [{directory: path.resolve(appDirectory, 'web/public')}],
historyApiFallback: {
index: path.resolve(appDirectory, 'web'),
},
},
entry: path.resolve(appDirectory, 'src', 'main'),
output: {
clean: true,
path: path.resolve(appDirectory, 'web/dist'),
filename: '[name].[chunkhash].js',
sourceMapFilename: '[name].[chunkhash].map',
chunkFilename: '[id].[chunkhash].js',
},
resolve: {
extensions: [
'.web.js',
'.js',
'.web.ts',
'.ts',
'.web.jsx',
'.jsx',
'.web.tsx',
'.tsx',
],
alias: {
'react-native$': 'react-native-web',
},
},
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
plugins: [
// Fast refresh plugin
new ReactRefreshWebpackPlugin(),
// Plugin that takes public/index.html and injects script tags with the built bundles
new HtmlWebpackPlugin({
template: path.resolve(appDirectory, 'web/public/index.html'),
}),
// Defines __DEV__ and process.env as not being null
new webpack.DefinePlugin({
__DEV__: argv.mode !== 'production' || true,
process: {env: {}},
}),
new CopyWebpackPlugin({
patterns: [
{
from:
path.resolve(appDirectory, 'web/public') +
'/**/!(*.html|*.ttf|*.woff|*.css|*.png|*.ico|*.svg)',
to() {
return path.resolve(appDirectory, 'web/dist') + '/[name][ext]';
},
},
{
from:
path.resolve(appDirectory, 'web/public/fonts') +
'/**/(*.ttf|*.woff)',
to() {
return (
path.resolve(appDirectory, 'web/dist/fonts') + '/[name][ext]'
);
},
},
{
from: path.resolve(appDirectory, 'web/public/styles') + '/**/*.css',
to() {
return (
path.resolve(appDirectory, 'web/dist/styles') + '/[name][ext]'
);
},
},
{
from:
path.resolve(appDirectory, 'web/public/images') +
'/**/(*.png|*.ico|*.svg)',
to() {
return (
path.resolve(appDirectory, 'web/dist/images') + '/[name][ext]'
);
},
},
],
}),
],
optimization: {
// Split into vendor and main js files
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'initial',
},
},
},
},
};
};
Dev server command:
webpack-dev-server --config {projectRoot}/web/webpack.config.js --mode development --history-api-fallback
Production server command:
webpack --config {projectRoot}/web/webpack.config.js --mode production
Could anyone please provide guidance on how to resolve this issue? Any suggestions or insights would be greatly appreciated.