I am trying to run a test in next.js using jest that imports firebase, but i keep getting an error:
{import { registerVersion } from '#firebase/app'; SyntaxError: Cannot use import statement outside a module
Importing other modules works, but firebase throughs that error. I have tried other enviroments but none seem to work and either throw this error or another error.
Package.JSON:
{
"name": "chat",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest --forceExit --watchAll --coverage"
},
"dependencies": {
"#firebase/testing": "^0.20.11",
"firebase": "^9.9.4",
"kill-port": "^2.0.1",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-firebase-hooks": "^5.0.3",
"react-hot-toast": "^2.3.0",
"uuid": "^8.3.2"
},
"devDependencies": {
"#babel/plugin-syntax-jsx": "^7.18.6",
"#babel/preset-react": "^7.18.6",
"#firebase/rules-unit-testing": "^2.0.4",
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#types/jest": "^29.0.2",
"eslint": "8.23.0",
"eslint-config-next": "12.2.5",
"firebase-admin": "^11.0.1",
"jest": "^29.0.3",
"jest-environment-jsdom": "^29.0.3"
}
}
Jest.config.js:
// jest.config.js
const nextJest = require('next/jest');
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
});
// Add any custom config to be passed to Jest
/** #type {import('jest').Config} */
const customJestConfig = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
//moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
test/page.test.js
/**
* #jest-environment jest-environment-jsdom
*/
import React from 'react';
import { render, screen } from '#testing-library/react';
import Thing from '../../pages/thing.jsx';
describe('testing Home page', () => {
test('render h1 element', () => {
expect(render(<Thing />));
});
});
pages/test.jsx
import { firestore } from "../lib/firebase";
export default function Thing({ }) {
return (
<main>
</main>
);
}
lib/firebase (Note: removed config fields)
import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getStorage } from 'firebase/storage';
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const googleAuthProvider = new GoogleAuthProvider();
export const firestore = getFirestore(app);
export const storage = getStorage(app);
Related
I already used Firebase on another app recently. But this time I'm getting that error on console.
It's throwing this error on page
ERROR in ./src/Context/AuthContext.jsx 8:0-49
ERROR in ./src/Firebase.js 4:0-45
and this on console
bundle.js:1861 Uncaught Error: Cannot find module 'firebase/app'
at webpackMissingModule (bundle.js:1861:50)
at ./src/Firebase.js (bundle.js:1861:137)
at options.factory (bundle.js:126646:31)
at webpack_require (bundle.js:126092:33)
at fn (bundle.js:126303:21)
at ./src/Context/AuthContext.jsx (bundle.js:1641:67)
at options.factory (bundle.js:126646:31)
at webpack_require (bundle.js:126092:33)
at fn (bundle.js:126303:21)
at ./src/App.js (bundle.js:20:78)
This is my Firebase.js file
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const db = getFirestore(app);
export default app;
And this provider context file
import { createContext, useContext, useState, useEffect } from "react";
import { auth, db } from "../Firebase";
import { doc, setDoc } from "firebase/firestore";
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
} from "firebase/auth";
const UserContext = createContext();
export const AuthContextProvider = ({ children }) => {
const [user, setUser] = useState({});
const signUp = (email, password) => {
createUserWithEmailAndPassword(auth, email, password);
return setDoc(doc(db, "users", email), {
favList: [],
});
};
const signIn = (email, password) => {
return signInWithEmailAndPassword(auth, email, password);
};
const logout = () => {
return signOut(auth);
};
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
});
return () => {
unsubscribe();
};
}, []);
return (
<UserContext.Provider value={{ signUp, signIn, logout, user }}>
{children}
</UserContext.Provider>
);
};
export const UserAuth = () => {
return useContext(UserContext);
};
package.json
{
"name": "cryptotracker-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"axios": "^1.3.1",
"dompurify": "^2.4.3",
"firebase": "^9.17.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.7.1",
"react-router-dom": "^6.8.0",
"react-scripts": "5.0.1",
"react-sparklines": "^1.7.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"tailwindcss": "^3.2.4"
}
}
I tried most of things like uninstall and install but they didn't work.
I am also getting the same error,but after removing the firebase version 9.17.0 and reinstalling firebase with its 9.16.0 vesrion all the error has been resolved.
Latest version of firebase might be unstable.
I'm trying to use returned promise from VueFire method $databaseBind (here is the VueFire doc), but unfortunately and I don't know why I have an error this.$databaseBind(...).then() is not a function.
I know that we can have this error when we try call then on non promise value, but $databaseBind should return a promise.
reproduction in codesandbox https://codesandbox.io/s/strange-borg-y41d0u?file=/src/App.vue
Here is my main.js
import { createApp } from "vue";
import App from "./App.vue";
import { VueFire, VueFireDatabaseOptionsAPI } from "vuefire";
createApp(App)
.use(VueFire, {
modules: [VueFireDatabaseOptionsAPI()],
})
.mount("#app");
package.json
{
"name": "happy-new-year",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"firebase": "^9.15.0",
"vue": "^3.2.13",
"vuefire": "^3.0.0"
},
"devDependencies": {
"#babel/core": "^7.12.16",
"#babel/eslint-parser": "^7.12.16",
"#vue/cli-plugin-babel": "~5.0.0",
"#vue/cli-plugin-eslint": "~5.0.0",
"#vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
},
}
firebase.js
import { initializeApp } from "firebase/app";
import { getDatabase } from "firebase/database";
import "firebase/database";
import "firebase/storage";
import "firebase/auth";
const config = {};
export const fb = initializeApp(config);
export const db = getDatabase(fb);
and usage
<template>
<div>{{ testObject.$value }}</div>
</template>
<script>
import { ref } from "firebase/database";
import { db } from "#/plugins/firebase";
export default {
name: "App",
data() {
return {
testObject: {},
};
},
mounted() {
this.$databaseBind("testObject", ref(db, path)).then();
},
};
</script>
Do somebody have any suggestion? Thanks a lot!
There was an inner bug of VueFire. They have fixed it already.
https://github.com/vuejs/vuefire/issues/1275
I'm getting the following error:
Error: Directory import 'C:\Users\My Name\Documents\Code\WebProjects\nextfire-app\node_modules\firebase\app' is not supported resolving ES modules imported from C:\Users\My Name\Documents\Code\WebProjects\nextfire-app.next\server\pages\enter.js
Did you mean to import firebase/app/dist/index.cjs.js?
import firebase from "firebase/app"
import "firebase/auth";
import "firebase/firestore";
import "firebase/storage";
const firebaseConfig = {
// myConfig stuff
};
if (!firebase.app.length) {
firebase.initializeApp(firebaseConfig)
}
export const auth = firebase.auth();
export const firestore = firebase.firestore();
export const storage = firebase.storage();
This code is inside firebase.js which gets called from enter.js using this line
import { auth, googleAuthProvider } from "../lib/firebase";
This is my package.json:
{
"name": "nextfire-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"firebase": "^8.2.1",
"next": "12.1.6",
"react": "18.1.0",
"react-dom": "18.1.0",
"react-firebase-hooks": "^5.0.3",
"react-hot-toast": "^2.2.0"
},
"devDependencies": {
"eslint": "8.15.0",
"eslint-config-next": "12.1.6"
}
}
I'm not even sure what this error is trying to tell me so it's been very difficult to debug. I also haven't seen anyone else with a similar issue.
After a bit more trying I was actually able to solve the problem by changing my import lines in firebase.js to what the error was suggesting.
My new imports look like this:
import firebase from "firebase/app/dist/index.cjs.js"
import "firebase/auth/dist/index.cjs.js";
import "firebase/firestore/dist/index.node.cjs.js";
import "firebase/storage/dist/index.cjs.js";
A strange issue that I still don't understand but I at least have it working, if anyone with more experience knows why this issue occurred in the first place, I'd love to understand more about it.
I've used this test in the past with a React app without any issues:
import { render, fireEvent, screen, waitFor } from '#testing-library/react'
import { RelatedContent } from '../components/relatedcontent'
import { onValue } from '../components/firebase'
jest.mock('../components/firebase')
test('RelatedContent -> displays related content', async () => {
let fakeData = {
'flex-new-row': 20,
'chronlabs': 25
}
let snapshot = {val: () => fakeData}
onValue.mockImplementation((ref, callback) => {
callback(snapshot)
return jest.fn()
})
render(<RelatedContent numRelated = {5}/>)
await waitFor(() => expect(document.querySelector("a[href='/flex-new-row']")).toBeTruthy())
await waitFor(() => expect(document.querySelector("a[href='/chronlabs']")).toBeTruthy())
})
Now I'm using the same test on a Next.js app, and I'm getting the following error:
TypeError: _firebase.onValue.mockImplementation is not a function
Update
The RelatedContent component looks like:
import React, { useState, useEffect } from 'react'
import { db, onValue, ref } from './firebase'
const RelatedContent = ({ numRelated }) => {
const [related, setRelated] = useState([])
useEffect(() => {
let unsubscribe = onValue(ref(db, `posts/related`), snapshot => {
let _related = Object.keys(snapshot.val())
setRelated(_related)
})
return () => unsubscribe()
}, [])
return(
<div className = 'Related'>
{related.slice(0, numRelated).map((elem, i) =>
<Link href = {elem}>Whatever</Link>
)}
</div>
)
}
export default RelatedContent
And the Firebase component looks like:
import { initializeApp } from 'firebase/app'
import { getDatabase, goOnline, goOffline, limitToLast, onDisconnect, onValue, orderByValue, push, query, ref, remove, runTransaction, update } from 'firebase/database'
const config = { ... }
const app = initializeApp(config)
const db = getDatabase(app)
export { db, dbt, goOnline, goOffline, limitToLast, onDisconnect, onValue, orderByValue, push, query, ref, remove, runTransaction, update }
package.json looks like:
{
"name": "app-next",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest"
},
"dependencies": {
"#primer/octicons-react": "^16.3.0",
"chart.js": "^2.7.2",
"firebase": "^9.6.4",
"gfm": "0.0.1",
"moment": "^2.29.1",
"next": "12.0.8",
"prismjs": "^1.26.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-markdown": "^8.0.0",
"rehype-katex": "^6.0.2",
"rehype-raw": "^6.1.1",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1"
},
"devDependencies": {
"#testing-library/jest-dom": "^5.16.1",
"#testing-library/react": "^12.1.2",
"eslint": "8.7.0",
"eslint-config-next": "12.0.8",
"eslint-plugin-promise": "^6.0.0",
"jest": "^27.4.7"
}
}
If I place the fake data and the onValue.mockImplementation() function before the test declaration, the test passes correctly.
The problem is that I've several tests with multiple definitions of the fake data, and I need to declare the fake data within every test.
If I do so, I get the error.
My firebase has some problems which the console says firestore is undefined. I think the problem actually comes from my firebaseApp or somewhere but i don't know how to fix it. it'd be kind of you guys to help me! Thank you so much!
This is my firebase.js:
import firebase from 'firebase';
const firebaseApp = firebase.initializeApp[{
apiKey: "<API_KEI>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
projectId: "<PROJECT_ID>",
storageBucket: "<PROJECT_ID>.appspot.com",
messagingSenderId: "<SENDER_ID>",
appId: "<APP_ID>",
measurementId: "<MESURMENT_ID>"
}];
const db = firebaseApp.firestore();
const auth = firebase.auth();
export {
auth,
db
};
This is my SignIn.js:
import React from "react";
import firebase from "firebase";
import {
auth
} from "../firebase.js";
function SignIn() {
function signInWithGoogle() {
const provider = new firebase.auth.GoogleAuthProvider();
auth.signInWithPopup(provider);
}
return ( <
div >
<
button onClick = {
signInWithGoogle
} > Sign in with google < /button>{" "} <
/div>
);
}
This is my App.js:
import React from 'react'
import SignIn from './components/SignIn'
import Chat from './components/Chat'
function App() {
return ( <
div >
<
SignIn / >
<
Chat / >
<
/div>
)
}
export default App
This is my package.json:
{
"name": "image-search",
"version": "0.1.0",
"private": true,
"dependencies": {
"#emotion/react": "^11.4.1",
"#emotion/styled": "^11.3.0",
"#fortawesome/fontawesome-free": "^5.15.4",
"#material-ui/core": "^4.12.3",
"#material-ui/icons": "^4.11.2",
"#mui/icons-material": "^5.0.1",
"#mui/material": "^5.0.1",
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/react": "^11.2.7",
"#testing-library/user-event": "^12.8.3",
"firebase": "^8.10.0",
"font-awesome": "^4.7.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-firebase-hooks": "^3.0.4",
"react-scripts": "4.0.3",
"uuidv4": "^6.2.12",
"web-vitals": "^1.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/preset-react": "^7.14.5"
}
}
You can use latest firebase and check the docs below.
In your code, const db = firebaseApp.firestore();, but latest version use const db = getFirestore(app); to initialize db.
This is a demo from official network.
import { initializeApp } from 'firebase/app';
import { getFirestore, collection, getDocs } from 'firebase/firestore/lite';
// Follow this pattern to import other Firebase services
// import { } from 'firebase/<service>';
// TODO: Replace the following with your app's Firebase project configuration
const firebaseConfig = {
//...
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
// Get a list of cities from your database
async function getCities(db) {
const citiesCol = collection(db, 'cities');
const citySnapshot = await getDocs(citiesCol);
const cityList = citySnapshot.docs.map(doc => doc.data());
return cityList;
}
And find more information in this page firebase