firebase.auth() hangs when chrome debugging is on - firebase

Using the same credentials the login login action hangs at firebase.auth() when chrome debug is on. It hangs until I tap on the screen. Only then the login proceeds.
As soon as I turn chrome debug off, the login action incl. firebase.auth() runs as fast as expected.
here is my package.json an the affected action:
Action:
export const loginUser = ({ email, password }) => (dispatch) => {
dispatch({ type: LOGIN_USER });
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((user) => {
setTimeout(() => null, 0);
dispatch(() => saveCredentials(email, password))
.then(dispatch(loginUserSuccess(user)))
.then(dispatch(weekplanFetch()))
.then(dispatch(recipeLibraryFetch()))
.then(() => {
NavigationService.navigate('Home');
});
})
.catch((error) => {
console.log(`sign in fail ${error}`);
return firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((user) => {
dispatch(() => saveCredentials(email, password))
.then(dispatch(loginUserSuccess(user)))
.then(dispatch(initWeekplan()))
.then(dispatch(initRecipeLibrary()))
.then(() => {
NavigationService.navigate('Home');
});
})
.catch((userCreateFail) => {
// console.log(`user create fail ${userCreateFail}`);
dispatch(loginUserFail(userCreateFail.message));
});
});
};
package.json
{
"name": "WhatsForDinner",
"version": "1.0.5",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"ios:beta": "(cd ios/ && bundle exec fastlane beta)",
"ios:commit": "cd ios/ && bundle exec fastlane commit",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prettier": "prettier --write '*.js'",
"format-code": "yarn run prettier && yarn run lint:fix",
"precommit": "lint-staged",
"test:coverage": "jest --coverage && open coverage/lcov-report/index.html"
},
"lint-staged": {
"*.js": [
"yarn run format-code",
"git add",
"jest --bail --findRelatedTests --coverage"
]
},
"dependencies": {
"firebase": "^5.8.6",
"prop-types": "^15.6.0",
"react": "16.6.3",
"react-native": "0.57.8",
"react-native-code-push": "^5.5.2",
"react-native-image-picker": "^0.28.0",
"react-native-keychain": "^3.0.0",
"react-native-paper": "^1.12.0",
"react-native-vector-icons": "^6.4.1",
"react-navigation": "^1.6.1",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"yarn": "^1.9.4"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"babel-jest": "^23.4.2",
"babel-preset-react-native": "^5",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"eslint": "^4.18.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.12.3",
"husky": "^0.14.3",
"jest": "22.4.2",
"jest-fetch-mock": "^2.1.0",
"lint-staged": "^7.2.2",
"prettier": "1.10.2",
"react-dom": "^16.7.0",
"react-test-renderer": "16.4.1",
"redux-mock-store": "^1.5.3"
},
"jest": {
"preset": "react-native",
"setupFiles": [
"<rootDir>/tests/setup.js"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"collectCoverageFrom": [
"app/**/*.js",
"!app/components/index.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation)"
]
}
}

Related

How to build next.js app with custom server for production

I have created a next.js app in there I have a custom server dir. I am using koa.js as my custom server. It works fine on development but, when I build the app, the api routes show 404 not found error. Below is my package.json
{
"name": "dogs",
"version": "0.1.0",
"private": true,
"engines": {
"node": ">=18.7.0",
"yarn": ">=1.22.17",
"npm": "please-use-yarn"
},
"scripts": {
"dev": "nodemon ./server/index.js",
"ngrok": "ngrok http 3000",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prettier": "prettier --write .",
"prepare": "husky install",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"dependencies": {
"#babel/polyfill": "^7.12.1",
"#babel/preset-env": "^7.20.2",
"#babel/register": "^7.18.9",
"#fireworks-js/preact": "^2.10.1",
"#koa/cors": "^4.0.0",
"#next/font": "13.1.1",
"#react-email/button": "^0.0.6",
"#react-email/container": "^0.0.7-canary.1",
"#react-email/head": "^0.0.4",
"#react-email/hr": "^0.0.4",
"#react-email/html": "^0.0.4",
"#react-email/img": "^0.0.4",
"#react-email/link": "^0.0.4",
"#react-email/preview": "^0.0.5",
"#react-email/render": "^0.0.6",
"#react-email/section": "^0.0.7-canary.1",
"#react-email/text": "^0.0.4",
"#sendgrid/mail": "^7.7.0",
"TagCloud": "^2.3.2",
"autoprefixer": "^10.4.13",
"aws-sdk": "^2.1300.0",
"babel-polyfill": "^6.26.0",
"bcryptjs": "^2.4.3",
"daisyui": "^2.47.0",
"dotenv": "^16.0.3",
"eslint": "8.30.0",
"eslint-config-next": "13.1.1",
"express": "^4.18.2",
"framer-motion": "^9.0.1",
"gsap": "^3.11.4",
"isomorphic-fetch": "^3.0.0",
"jsonwebtoken": "^9.0.0",
"koa": "^2.14.1",
"koa-body": "^6.0.1",
"koa-cache-control": "^2.0.0",
"koa-combine-routers": "^4.0.2",
"koa-conditional-get": "^3.0.0",
"koa-cookie": "^1.0.0",
"koa-etag": "^4.0.0",
"koa-mongo": "^1.9.3",
"koa-multer": "^1.0.2",
"koa-router": "^12.0.0",
"koa-session": "^6.2.0",
"koa-static": "^5.0.0",
"koa-static-cache": "^5.1.4",
"mongodb": "^4.13.0",
"mongoose": "^6.8.2",
"multer": "^1.4.5-lts.1",
"next": "13.1.1",
"postcss": "^8.4.20",
"primereact": "^8.7.3",
"react": "18.2.0",
"react-confetti": "^6.1.0",
"react-dom": "18.2.0",
"react-icons": "^4.7.1",
"react-multi-select-component": "^4.3.4",
"react-particles": "^2.8.0",
"react-select": "^5.7.0",
"react-tsparticles": "^2.8.0",
"split-type": "^0.3.3",
"tailwindcss": "^3.2.4",
"tsparticles": "^2.8.0",
"tsparticles-engine": "^2.8.0",
"tsparticles-preset-fireworks": "^2.8.0",
"winston": "^3.8.2"
},
"devDependencies": {
"#babel/core": "^7.20.7",
"#commitlint/cli": "^17.3.0",
"#commitlint/config-conventional": "^17.3.0",
"#storybook/addon-actions": "^6.5.15",
"#storybook/addon-essentials": "^6.5.15",
"#storybook/addon-interactions": "^6.5.15",
"#storybook/addon-links": "^6.5.15",
"#storybook/builder-webpack5": "^6.5.15",
"#storybook/manager-webpack5": "^6.5.15",
"#storybook/react": "^6.5.15",
"#storybook/testing-library": "^0.0.13",
"babel-loader": "^8.3.0",
"cross-env": "^7.0.3",
"husky": "^8.0.2",
"ngrok": "^4.3.3",
"nodemon": "^2.0.20",
"prettier": "^2.8.1"
},
"resolutions": {
"webpack": "^5"
}
}
Below is my server code
import '#babel/polyfill';
import dotenv from 'dotenv';
import 'isomorphic-fetch';
import next from 'next';
import Koa from 'koa';
import Router from 'koa-router';
import UserRouter from './routes/user';
import DataRouter from './routes/data';
import EmailRouter from './routes/emails';
import MongoClientConnection from './db';
import cookie from 'koa-cookie';
dotenv.config();
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const server = new Koa();
const router = new Router();
// Initialize NextJs instance and expose request handler
const app = next({ dev });
const handler = app.getRequestHandler();
(async () => {
try {
await app.prepare();
router.get('/custom-page', async (ctx) => {
await app.render(ctx.req, ctx.res, '/', ctx.query);
ctx.respond = false;
});
const db = await MongoClientConnection.Get();
server.context.db = db;
const handleRequest = async (ctx) => {
await handler(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
router.get('/_next/webpack-hmr', handleRequest); // Webpack content is clear
router.get('(.*)', async (ctx) => {
await handleRequest(ctx);
});
server.use(cookie());
server.use(UserRouter.routes()).use(UserRouter.allowedMethods());
server.use(DataRouter.routes()).use(DataRouter.allowedMethods());
server.use(EmailRouter.routes()).use(EmailRouter.allowedMethods());
server.use(router.routes());
server.listen(port, (_) => console.log(`App running on port ${port}`));
} catch (e) {
console.error(e);
process.exit();
}
})();
How can I build my next.js app so my api routes work on production?

Get refreshToken react-native firebase and #react-native-google-signin/google-signin

I need to get my accessToken and my refreshToken when I authenticate with fireabse. I have read a lot of the documentation and I can't understand how to get the refreshToken.
I get the accessToken from the GoogleSignIn.getTokens() method.
But I can't get the refreshToken from any method or function that these libraries provide me.
I need accessToken and refreshToken to send it to my backend. In other applications I am already receiving it, through other methods, but what would be the problem here? is the library wrong? I am not understanding the documentation? Why can't I really understand where to get it from or if the idToken updates itself or maybe the refreshToken is not sent anymore?
my code =>
import { GoogleSignin } from '#react-native-google-signin/google-signin';
import auth from '#react-native-firebase/auth';
GoogleSignin.configure({
webClientId:
'xxxxxxxxxxxxxxxxxxxxx',
});
const onGoogleButtonPress = async () => {
// Get the users ID token
const { idToken } = await GoogleSignin.signIn();
// Create a Google credential with the token
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
// Sign-in the user with the credential
return auth().signInWithCredential(googleCredential);
};
export { onGoogleButtonPress };
React Native Info =>
react: 18.1.0 => 18.1.0
react-native: 0.70.6 => 0.70.6
Package.json ->
{
"name": "asset_management_mobile",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#invertase/react-native-apple-authentication": "^2.2.2",
"#react-native-firebase/app": "^15.4.0",
"#react-native-firebase/auth": "^15.4.0",
"#react-native-google-signin/google-signin": "^8.0.0",
"#react-native-masked-view/masked-view": "0.2.0",
"#react-navigation/bottom-tabs": "^6.5.2",
"#react-navigation/native": "^6.0.12",
"#react-navigation/stack": "^6.2.3",
"#types/react-native-background-timer": "^2.0.0",
"convert-string": "^0.1.0",
"depcheck": "^1.4.3",
"deprecated-react-native-prop-types": "^2.3.0",
"react": "18.1.0",
"react-native": "0.70.6",
"react-native-android-open-settings": "^1.3.0",
"react-native-background-timer": "^2.4.1",
"react-native-ble-manager": "^8.4.3",
"react-native-bluetooth-state-manager": "^1.3.4",
"react-native-gesture-handler": "^2.6.0",
"react-native-gradle-plugin": "^0.70.2",
"react-native-linear-gradient": "^2.6.2",
"react-native-permissions": "^3.6.1",
"react-native-reanimated": "^2.10.0",
"react-native-safe-area-context": "^4.3.3",
"react-native-screens": "^3.17.0",
"react-native-splash-screen": "^3.3.0",
"react-native-svg": "^13.1.0",
"react-native-swiper": "^1.6.0",
"react-native-vision-camera": "^2.15.2",
"vision-camera-code-scanner": "^0.2.0"
},
"devDependencies": {
"#babel/core": "^7.14.6",
"#babel/runtime": "^7.14.6",
"#react-native-community/eslint-config": "^3.0.0",
"#types/convert-string": "^0.1.1",
"#types/jest": "^29.0.0",
"#types/react": "^18.0.18",
"#types/react-native": "^0.69.6",
"#types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.0.1",
"babel-plugin-module-resolver": "^4.1.0",
"eslint": "^8.23.0",
"jest": "^29.0.1",
"metro-react-native-babel-preset": "^0.72.1",
"react-native-svg-transformer": "^1.0.0",
"react-native-typescript-transformer": "^1.2.13",
"react-test-renderer": "^18.2.0",
"ts-jest": "^28.0.8",
"typescript": "^4.3.5"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}
I need your help!! Thanks!

Error: This action with HTTP GET is not supported by NextAuth.js

Unable to authenticate my Next.js app with credentials.
Error: This action with HTTP GET is not supported by NextAuth.js
As far as I know everything is correct according to the doc. and it was working too. it suddenly start returning this error.
package.json
{
"name": "materio-mui-react-nextjs-admin-template-free",
"description": "Most Powerful & Comprehensive Free MUI React NextJS Admin Dashboard Template built for developers! 🚀",
"license": "MIT",
"version": "1.0.0",
"author": {
"name": "IWorkplc",
"url": "https://iworkplc.com/"
},
"bugs": {
"url": "https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free/issues"
},
"private": false,
"repository": {
"type": "git",
"url": "https://github.com/themeselection/materio-mui-react-nextjs-admin-template-free.git"
},
"homepage": "https://themeselection.com/products/materio-free-mui-react-nextjs-admin-template/",
"keywords": [
"react",
"javascript",
],
"scripts": {
"info": "next info",
"dev": "next dev",
"build": "next build",
"start": "next start",
"export": "next export",
"lint": "eslint --fix \"src/**/*.{js,jsx}\"",
"format": "prettier --write \"src/**/*.{js,jsx}\"",
"postinstall": "patch-package"
},
"dependencies": {
"#emotion/cache": "^11.6.0",
"#emotion/react": "^11.7.0",
"#emotion/server": "^11.4.0",
"#emotion/styled": "^11.6.0",
"#iconify/react": "^4.0.0",
"#material-ui/icons": "^4.11.3",
"#mui/icons-material": "^5.10.15",
"#mui/lab": "^5.0.0-alpha.70",
"#mui/material": "^5.4.3",
"#popperjs/core": "^2.11.2",
"#react-oauth/google": "^0.5.0",
"#reduxjs/toolkit": "^1.9.0",
"apexcharts-clevision": "3.28.5",
"axios": "^1.2.0",
"apisauce": "^2.1.6",
"babel-eslint": "^10.1.0",
"clsx": "^1.1.1",
"formik": "^2.2.9",
"mdi-material-ui": "^7.1.0",
"moment": "^2.29.4",
"next": "12.3.1",
"next-auth": "^4.14.0",
"nprogress": "^0.2.0",
"react": "17.0.2",
"react-apexcharts": "^1.3.9",
"react-datepicker": "^4.5.0",
"react-dom": "17.0.2",
"react-perfect-scrollbar": "^1.5.8",
"react-popper": "^2.2.5",
"react-redux": "^8.0.5",
"react-toastify": "^9.1.1",
"react-use-websocket": "^4.2.0",
"redux-logger": "^3.0.6",
"socket.io-client": "^4.5.4",
"yup": "^0.32.11"
},
"devDependencies": {
"eslint": "^7.32.0",
"eslint-config-next": "12.0.4",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"next-transpile-modules": "^9.0.0",
"patch-package": "^6.5.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "2.5.1"
}
}
pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth'
import GoogleProvider from 'next-auth/providers/google'
import { getToken } from 'next-auth/jwt'
export const authOptions = {
// Configure one or more authentication providers
// debug: true,
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
authorization: {
params: {
scope:
'openid email profile https://www.googleapis.com/auth/gmail.compose https://www.googleapis.com/auth/gmail.modify'
}
},
idToken: true
}),
{
clientId: process.env.QUICK_BOOKS_CLIENT_ID,
clientSecret: process.env.QUICK_BOOKS_CLIENT_SECRET,
id: 'quickbooks',
name: 'QuickBooks',
type: 'oauth',
wellKnown: 'https://developer.api.intuit.com/.well-known/openid_sandbox_configuration',
authorization: { params: { scope: 'com.intuit.quickbooks.accounting openid profile email phone address' } },
userinfo: {
async request(context) {
return await context.client.userinfo(context.tokens.access_token)
}
},
idToken: true,
checks: ['pkce', 'state'],
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture
}
}
},
// ...add more providers here
{
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
id: 'googledrive',
name: 'Google Drive',
type: 'oauth',
wellKnown: 'https://accounts.google.com/.well-known/openid-configuration',
authorization: {
params: {
scope:
'openid email profile https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.resource'
}
},
idToken: true,
checks: ['pkce', 'state'],
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture
}
}
}
],
callbacks: {
async session({ session, token, user }) {
session.user.id = token?.id
session.accessToken = token?.accessToken
session.provider = token?.account?.provider
return session
},
async jwt({ token, user, account, profile, isNewUser }) {
if (user) {
token.user = user
}
if (account) {
token.account = account
}
return token
}
}
}
export default NextAuth(authOptions)
i tried by upgrading both next and next-auth packages but it didn't work.
[...nextauth].js is inside pages/api/auth

Firebase Deploy Unexpected token

I am getting the error Parsing error: Unexpected token => when I try to deploy my Vue JS application to firebase. The application runs fine on my local machine but I am not able to deploy to firebase.
Here is the full error
=== Deploying to 'mmmmnl-d5ddc'...
i deploying storage, firestore, functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run lint
> lint
> eslint .
/Users/KingdomMac/Downloads/ermnl_delivery/ermnl-dashboard/functions/index.js
22:71 error Parsing error: Unexpected token =>
✖ 1 problem (1 error, 0 warnings)
Error: functions predeploy error: Command terminated with non-zero exit code1
I have added ecmaVersion: 8 to parserOptions. I have changed it to 6, I have also changed it to 2017 as suggested by some other answers.
Here is my .eslintrc.js file
module.exports = {
root: true,
env: {
node: true
},
extends: ["plugin:vue/essential", "#vue/prettier"],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
},
parserOptions: {
parser: 'babel-eslint',
ecmaVersion: 2017
},
'extends': [
'plugin:vue/essential',
'#vue/prettier',
'#vue/standard'
]
};
Here is my package.json file
{
"name": "vue-white-dashboard",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^1.2.35",
"#fortawesome/free-brands-svg-icons": "^5.15.3",
"#fortawesome/free-regular-svg-icons": "^5.15.3",
"#fortawesome/free-solid-svg-icons": "^5.15.3",
"#fortawesome/vue-fontawesome": "^2.0.2",
"axios": "^0.21.1",
"chart.js": "^2.8.0",
"core-js": "^2.6.5",
"firebase": "^8.6.8",
"node-sass": "^6.0.1",
"vue": "^2.6.10",
"vue-chartjs": "^3.4.2",
"vue-click-outside": "^1.0.7",
"vue-clickaway": "^2.2.2",
"vue-github-buttons": "^3.1.0",
"vue-i18n": "^8.14.1",
"vue-router": "^3.0.3",
"vue-social-sharing": "^2.4.6",
"vue2-transitions": "^0.3.0",
"vuetify": "^2.4.0"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^3.3.0",
"#vue/cli-plugin-eslint": "^3.1.1",
"#vue/cli-service": "^4.5.15",
"#vue/eslint-config-prettier": "^5.0.0",
"#vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"eslint": "^8.2.0",
"eslint-config-eslint": "^7.0.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^7.14.0",
"prettier": "^1.18.2",
"sass": "~1.32",
"sass-loader": "^10.0.0",
"vue-cli-plugin-vuetify": "~2.4.1",
"vue-template-compiler": "^2.6.10",
"vuetify-loader": "^1.7.0"
}
}
None of the the other resources I have read points out the problem to be from their code. But I am just adding functions/index.js here incase the problem is from the that file.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
exports.addUserRole = functions.auth.user().onCreate(async (authUser) => {
if (authUser.email) {
const customClaims = {
admin: true,
};
try {
let _ = await admin.auth().setCustomUserClaims(authUser.uid, customClaims);
return db.collection("roles").doc(authUser.uid).set({
email: authUser.email,
role: customClaims,
});
} catch (error) {
console.log(error);
}
}
});
exports.setUserRole = functions.https.onCall(async (data, context) => {
if (!context.auth.token.admin) return
try {
let _ = await admin.auth().setCustomUserClaims(data.uid, data.role)
return db.collection("roles").doc(data.uid).update({
role: data.role
})
} catch (error) {
console.log(error)
}
});
As requested in the comments, I have added my firebase.json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
],
"source": "functions"
},
"storage": {
"rules": "storage.rules"
},
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

#react-native-firebase breaking unit tests

I installed v6 of #react-native-firebase, it's working as expected but when I try to run a unit test I get the following error:
Jest encountered an unexpected token
Details:
/node_modules/#react-native-firebase/database/lib/index.js:18
import { isBoolean, isNumber, isString } from '#react-native-firebase/app/lib/common';
^
SyntaxError: Unexpected token {
I tried adding #react-native-firebase/database & #react-native-firebase/app to jest config transformIgnorePatterns and get the following error:
Test suite failed to run
Invariant Violation: Native module cannot be null.
at invariant (node_modules/invariant/invariant.js:40:15)
at RNFBNativeEventEmitter.NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:36:7)
at new RNFBNativeEventEmitter (node_modules/#react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:24:5)
at Object.<anonymous> (node_modules/#react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:48:16)
at Object.<anonymous> (node_modules/#react-native-firebase/app/lib/internal/registry/nativeModule.js:21:1)
I also tried mocking the module with Jest like so:
import * as FBCommon from '#react-native-firebase/app/lib/common'
jest.mock(FBCommon, () => {
return () => ({
isBoolean: jest.fn(),
isNumber: jest.fn(),
isString: jest.fn()
})
});
and like this:
jest.mock('#react-native-firebase/database', () => {
return () => ({
ref: jest.fn()
})
});
but get the same error, any suggestions?
my package.json:
{
"name": "Project",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"#react-native-community/push-notification-ios": "^1.0.6",
"#react-native-firebase/app": "^6.3.1",
"#react-native-firebase/database": "^6.3.1",
"#react-native-firebase/messaging": "^6.3.1",
"axios": "^0.19.0",
"base-64": "^0.1.0",
"blinkid-react-native": "^5.2.0",
"firebase": "^7.6.0",
"lodash": "^4.17.15",
"mobx": "^5.15.0",
"mobx-persist": "^0.4.1",
"mobx-react": "^6.1.4",
"react": "16.9.0",
"react-native": "0.61.4",
"react-native-auth0": "^2.1.0",
"react-native-collapsible": "^1.5.1",
"react-native-config": "^0.12.0",
"react-native-confirmation-code-input": "^1.0.4",
"react-native-datepicker": "^1.7.2",
"react-native-device-info": "^5.4.1",
"react-native-elements": "^1.2.7",
"react-native-freshchat-sdk": "^2.3.0",
"react-native-gesture-handler": "^1.5.2",
"react-native-in-app-notification": "^3.0.1",
"react-native-keyboard-aware-scroll-view": "^0.9.1",
"react-native-phone-input": "^0.2.4",
"react-native-picker-select": "^6.3.3",
"react-native-push-notification": "^3.1.9",
"react-native-reanimated": "^1.4.0",
"react-native-screens": "^1.0.0-alpha.23",
"react-native-signature-capture": "^0.4.10",
"react-native-vector-icons": "^6.6.0",
"react-native-webview": "^8.0.3",
"react-navigation": "^4.0.10",
"react-navigation-stack": "^1.10.3"
},
"devDependencies": {
"#babel/core": "^7.7.2",
"#babel/runtime": "^7.7.2",
"#react-native-community/eslint-config": "^0.0.5",
"babel-jest": "^24.9.0",
"babel-plugin-module-resolver": "^4.0.0",
"chai": "^4.1.2",
"chai-enzyme": "1.0.0-beta.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"eslint": "^6.6.0",
"jest": "^24.9.0",
"jsdom": "15.2.1",
"jsdom-global": "3.0.2",
"metro-react-native-babel-preset": "^0.57.0",
"react-dom": "^16.12.0",
"react-test-renderer": "16.9.0",
"sinon": "^7.2.2"
},
"jest": {
"preset": "react-native",
"setupFilesAfterEnv": [
"./setUpTests.js"
],
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|#react-native-firebase/database|#react-native-firebase/app|react-clone-referenced-element|expo(nent)?|#expo(nent)?/.*|react-navigation|#react-navigation/.*|sentry-expo|native-base))"
]
}
}
You could mock firebase database by creating a mock module in a mocks directory like this:
mkdir -p __mocks__/#react-native-firebase/database
touch index.js
And use jest mocking functions in index.js for the firebase version and database functionalities to test. Something along these lines:
const database = {
functionality1: jest.fn(() => ({
propertyExample1: jest.fn(() => Promise.resolve(true)),
...
})),
...
functionality2: jest.fn(() => ({
property2: jest.fn(() => Promise.resolve(true)),...
})),
};
export default database;
This occurs because the native emitter isn't properly mocked by the library. Adding the following snippet at the top of your tests can resolve this by ensuring the module isn't null.
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter');
I solved the issue creating jest.setup.js file with the content:
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter');
And then in package.json inside jest
"setupFiles": ["./yourPath/jest.setup.js"],

Resources