I am having an issue that I can't figure out the solution, I built this page a while ago, and now I need to add an authentication section, I already had the firebase installed because of the deployment, so I as I wrote the code most of the methods wouldn't be recognized or appear. I tried to look for solutions, used firebase/compat/auth
but nothing. This is the code I have
the Firebase config file:
import firebase from 'firebase/app';
import 'firebase/firestore';
const firebaseConfig = {
apiKey: "xxxx",
authDomain: "xxx",
projectId: "xxx",
storageBucket: "xxxx",
messagingSenderId: "xxx",
appId: "xxx",
measurementId: "xxxx"
};;
const firebaseApp=firebase.initializeApp(firebaseConfig);
const db=firebase.firestore();
const auth = firebase.auth(firebaseApp);
export { auth }
export default db;
The implementation
import React, { useState } from 'react'
import {auth} from '../../firebase.config.js'
import {onAuthStateChanged,signInWithEmailAndPassword,signOut} from "firebase/auth"
function AppAuthentication(){
const [loginEmail,setLoginEmail] = useState("");
const [loginEmailPass, setLoginEmailPass] = useState("");
const [user,setUser] = useState({});
const login = async () => {
try{
const user = await signInWithEmailAndPassword(auth,loginEmail,loginEmailPass);
console.log(user)
}catch(error){
console.log(error)
}
}
const logout = async () => {
await signOut(auth)
}
return(
<>
<div>
<h3> Login</h3>
<br></br>
<input placeholder='Your email'
onChange={(event)=>{
setLoginEmail(event.target.value);
}}
/>
<br></br>
<input placeholder='Your Password'
onChange={(event)=>{
setLoginEmailPass(event.target.value)
}}
/>
<br></br>
<button onClick={login}>Login</button>
<br></br>
<h4>User:</h4>
<br></br>
<button onClick={logout}>Sign Out</button>
</div>
</>
)
}
export default AppAuthentication;
The Error message I get is:
Module '"firebase/auth"' has no exported member 'onAuthStateChanged'.
Module '"firebase/auth"' has no exported member 'signOut'.
This is the package.json
"dependencies": {
"#craco/craco": "^6.2.0",
"#firebase/auth": "^0.20.7",
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/react": "^11.2.7",
"#testing-library/user-event": "^12.8.3",
"#types/jest": "^26.0.24",
"#types/node": "^12.20.19",
"#types/react": "^17.0.18",
"#types/react-dom": "^17.0.9",
"firebase": "^8.10.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-dropdown": "^1.9.2",
"react-icons": "^4.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.3.5",
"web-vitals": "^1.1.2"
},
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject",
"deploy:firebase": "npm run build && firebase deploy"
},
"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": {
"#types/react-router-dom": "^5.1.8",
"autoprefixer": "^9.8.6",
"postcss": "^7.0.36",
"tailwindcss": "npm:#tailwindcss/postcss7-compat#^2.2.7"
}
}
Thanks in advance for thee help. my Firebase version in 8.10.1
Related
I am in the middle of making an Instagram Clone SSR project using React and Tailwind.CSS but I got stuck with Tailwind CSS I have installed the required dependencies, changed scripts that was needed also added paths in tailwindcss.config.js, added #tailwind directives to the app.css file also but whatever is written in class names is not reflecting in the result after npm start
Login.js file for Login Page
import { useContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import FirebaseContext from "../context/firebase";
import "../styles/app.css";
export default function Login() {
const navigate = useNavigate();
const { firebase } = useContext(FirebaseContext);
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const isInvalid = password === "" || emailAddress === "";
const handleLogin = () => {};
useEffect(() => {
document.title = "Login - Instagram";
}, []);
return (
<div className='container flex mx-auto max-w-screen-md items-center h-screen'>
<div className='flex w-3/5'>
<img
src='/images/iphone-with-profile.jpg'
alt='iPhone with Instagram App'
className='max-w-full'
/>
</div>
<div className='flex flex-col w-2/5'>
<p>This is the Form</p>
</div>
</div>
);
}
package.json file - scripts and dependencies
{
"name": "instagram",
"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",
"date-fns": "^2.29.3",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-loading-skeleton": "^3.1.0",
"react-router-dom": "^6.8.1",
"react-scripts": "^5.0.1",
"web-vitals": "^3.1.1"
},
"scripts": {
"build:css": "postcss src/styles/tailwind.css -o src/styles/app.css",
"watch:css": "postcss src/styles/tailwind.css -o src/styles/app.css --watch",
"react-scripts:start": "react-scripts start",
"start": "run-p watch:css react-scripts:start",
"build": "run-s build:css 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": {
"autoprefixer": "^10.4.13",
"babel-eslint": "^10.1.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-scope": "^7.1.1",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.21",
"postcss-cli": "^10.1.0",
"postcss-loader": "^7.0.2",
"prettier": "^2.8.4",
"tailwindcss": "^3.2.6"
}
}
postcss.config.js
module.exports = {
plugins: [require("tailwindcss"), require("autoprefixer")],
};
tailwind.config.js
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
},
theme: {
extend: {},
},
variants: {},
plugins: [],
content: ["./src/**/*.html", "./src/**/*.jsx", "./public/index.html"],
};
And in my app.css file the original file contained the "#tailwind" commands (base, utilities, components), but they were replaced with the generated CSS code that follows the defined styles in the Tailwind CSS configuration.
You should remove the curly braces in your classNames :
<div className='container flex mx-auto max-w-screen-md items-center h-screen'>
I think it's because your component's extension is .js but you don't have .js files covered in your Tailwind config (content property). I would recommend changing the extension of your component's file to .jsx.
I have recently completed a MERN stack web application and trying to deploy it on to Heroku. It looks like it's deployed but when I try to login or create user, it says 404 not found /graphql. When running heroku log --tails, it says after the post the app crashes due to memory usage over quota.
So I ran it locally and used DevTools to look at the memory usage. I noticed there were huge spikes for login, login, searching because it loops and populates the page with items for api. I am currently trying to refactor the searched and use react.lazy to only show what's in viewpoint of user. But as for login and signup, I really have no idea how to refactor it to use less memory.
This is my code for the frontend of login:
LoginPage.js
import { Link } from 'react-router-dom';
import { useMutation } from '#apollo/client';
import { authService } from '../utils/auth';
import { LoginForm } from '../components/Login/LoginForm'
import { Alert } from 'react-bootstrap';
import { LOGIN_USER } from '../utils/mutations';
export const Login = (props) => {
const [formState, setFormState] = useState({ email: '', password: '' });
const [login, { error }] = useMutation(LOGIN_USER);
const handleSubmit = (e) => {
const { name, value } = e.target;
setFormState({
...formState,
[name]: value,
});
};
// submit form
const handleFormSubmit = async (e) => {
e.preventDefault();
console.log(formState);
if (!formState.email || !formState.password) {
alert('Failed to submit form! Please fill all requested fields.');
document.location.replace('/');
}
try {
const { data } = await login({
variables: { ...formState },
});
authService.login(data.login.token)
} catch (e) {
console.log(e);
}
// clear form values
setFormState({
email: '',
password: '',
});
};
return (
<> {authService.loggedIn() ? (
<p>
Success! You may now head{' '}
<Link to="/">back to the homepage.</Link>
</p>
) : (
<LoginForm
onSubmit={handleFormSubmit}
handleSubmit={handleSubmit}
handleFormSubmit={handleFormSubmit}
formState={formState}
/>
)}
{error && (
<Alert severity='error'>
{error.message}
</Alert>
)}
</>
);
};
export default LoginForm;
LoginForm.js
import React from 'react'
import { Form, Button } from 'react-bootstrap';
export const LoginForm = ({handleFormSubmit, handleSubmit, formState}) => {
return (
<Form onSubmit={handleFormSubmit} style={{padding:'15%', justifyContent:'center'}}>
<Form.Group>
<Form.Label htmlFor='email'>Email</Form.Label>
<Form.Control
type='email'
placeholder='Your email'
name='email'
onChange={handleSubmit}
value={formState.email}
required
/>
<Form.Control.Feedback type='invalid'>Email is required!</Form.Control.Feedback>
</Form.Group>
<Form.Group>
<Form.Label htmlFor='password'>Password</Form.Label>
<Form.Control
type='password'
placeholder='Your password'
name='password'
onChange={handleSubmit}
value={formState.password}
required
/>
<Form.Control.Feedback type='invalid'>Password is required!</Form.Control.Feedback>
</Form.Group>
<Button style={{margin:'5%', justifyContent:'center', textAlign:'center'}}
disabled={!(formState.email && formState.password)}
type='submit'
variant='success'>
Submit
</Button>
</Form>
)
}
package.json in client
{
"name": "client",
"version": "0.1.0",
"private": true,
"engines": {
"node": "14.2.0",
"npm": "6.14.5"
},
"dependencies": {
"#apollo/client": "^3.7.3",
"#apollo/react-hooks": "^4.0.0",
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"apollo-cache-inmemory": "^1.6.6",
"apollo-cache-persist": "^0.1.1",
"apollo-client": "^2.6.10",
"apollo-link-http": "^1.5.17",
"apollo-link-rest": "^0.9.0",
"axios": "^1.2.2",
"bootstrap": "^5.2.3",
"graphql": "^15.8.0",
"http-proxy-middleware": "^2.0.6",
"jwt-decode": "^3.1.2",
"qs": "^6.11.0",
"react": "^18.2.0",
"react-bootstrap": "^2.7.0",
"react-dom": "^18.2.0",
"react-moment": "^1.1.3",
"react-router-dom": "^6.7.0",
"react-scripts": "^5.0.1",
"react-use": "^17.4.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"
]
},
"main": "index.js"
}
package.json in server
"name": "server",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"watch": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"apollo-server-express": "^3.11.1",
"axios": "^1.2.5",
"bcrypt": "^5.1.0",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"graphql": "^16.6.0",
"jsonwebtoken": "^9.0.0",
"mongoose": "^6.9.0",
"nodemon": "^2.0.20"
}
}
Package.json in root
{
"name": "foodgenie",
"version": "1.0.0",
"description": "",
"main": "server/server.js",
"scripts": {
"start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
"start:prod": "cd server && npm start",
"start:dev": "concurrently \"cd server && npm run watch\" \"cd client && npm start\"",
"install": "cd server && npm i && cd ../client && npm i",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"keywords": [],
"author": "Chris H",
"license": "ISC",
"dependencies": {
"concurrently": "^7.6.0",
"dotenv": "^16.0.3",
"if-env": "^1.0.4",
"nodemon": "^2.0.20"
}
}
Procfile
web: npm run start:dev
Any advice or feedback will be greatly appreciated. Thank you.
I hope you are having a fantastic day.
I am using this API: https://apify.com/petrpatek/covid-19-aggregator/api, for the first time, and I am having some issues getting it to work with React. This is the file where I am making my API call:
const ApifyClient = require('apify-client');
require('dotenv').config({ path: `${__dirname}/../../.env` });
const client = new ApifyClient({
token: process.env.REACT_APP_API_TOKEN,
});
const input = {};
const getItems = async () => {
// Run the actor and wait for it to finish
const run = await client.actor('petrpatek/covid-19-aggregator').call(input);
// Fetch and print actor results from the run's dataset (if any)
console.log('Results from dataset');
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// console.log(items);
items.forEach((item) => {
console.dir(item);
});
return items;
};
getItems();
// export default getItems();
Most of the above is just copy-pasted from the API docs, this file has no problems running as a standalone, if I run node apify.js, it returns the correct data as I expect:
correct data
However when I try to run it inside of a React component, like so:
import { useEffect } from 'react';
import CountryCard from '../components/countryCard';
import Header from '../components/header';
import getItems from '../APIs/apify';
const AllCountriesPage = () => {
useEffect(() => {
getItems();
}, []);
return (
<div className="allCountriesPage">
<Header />
<CountryCard className="bannerCountry" />
<p className="allCountriesText">All countries</p>
<div className="allCountriesContainer">
{/* Some kind of for loop */}
<CountryCard />
</div>
</div>
);
};
export default AllCountriesPage;
It throws the following error:
error message
At first, I thought this was just a problem with the dependencies, but I do have them installed, or the file would not be running by itself, also this is my package.js file:
{
"name": "catalogue-of-statistics",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"apify-client": "^1.2.4",
"dotenv": "^8.2.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1"
},
"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/core": "^7.14.5",
"#babel/eslint-parser": "^7.14.5",
"#babel/plugin-syntax-jsx": "^7.14.5",
"#babel/preset-react": "^7.14.5",
"eslint": "^7.28.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^21.0.0",
"stylelint-csstree-validator": "^1.9.0",
"stylelint-scss": "^3.19.0"
}
}
I see my colleague replied to you over our Discord.
For others:
You need to add mainFields: ['browser', 'main', 'module'], to your webpack config. The order is important. main needs to go before module. See https://webpack.js.org/configuration/resolve/#resolvemainfields
As Lukas was saying above, the Apify team answered my question directly in their discord, so I want to put the solution here if someone comes across it in the future.
You need to go to node_modules -> react_scripts -> config -> webpack.config.js inside the resolve: { ... } object, add this line: mainFields: ['browser', 'main', 'module'], make sure that main is before module.
I have a backend with users that i want to display on my frontend folder.
In order to do that i need authorization headers to be implemented in React via Apollo Server.
I followed some instruction from here -> https://www.apollographql.com/docs/react/networking/authentication/
This is my code inside App.js
import React from 'react';
import HeroesDota from './components/HeroesDota';
import { ApolloProvider } from '#apollo/react-hooks';
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
import { setContext } from 'apollo-link-context';
const httpLink = new HttpLink({
uri: "http://localhost:8000/graphql/",
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const App = () => {
return (
<ApolloProvider client={client}>
<HeroesDota />
</ApolloProvider>
)};
export default App;
After i run server on localhost:3000 it says: Uncaught Error: Cannot find module 'apollo-link-context'
I installed apollo-link as dependency. I dont know why this error show up. Here is the actual picture.
package.json
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"#apollo/react-hooks": "^3.1.3",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.4.0",
"#testing-library/user-event": "^7.2.1",
"apollo-boost": "^0.4.7",
"apollo-cache-inmemory": "^1.6.5",
"apollo-link": "^1.2.13",
"apollo-link-ws": "^1.0.19",
"bootstrap": "^4.4.1",
"graphql": "^14.5.8",
"react": "^16.12.0",
"react-apollo": "^3.1.3",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "^16.12.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.0",
"styled-components": "^5.0.0",
"subscriptions-transport-ws": "^0.9.16"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {}
}
You are importing it right here:
import { setContext } from 'apollo-link-context';
Please run npm i apollo-link-context to fix.
I want to test if my component displayed and I have an error with shallow (see an image of error).
I am using :
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"jest-enzyme": "^7.1.1",
"jest": "^24.8.0"
My test look:
import React from "react";
import { shallow } from "enzyme";
import Header from "./Header";
describe("Header Component", () => {
it("Should render without errors", () => {
let component = shallow(<Header />);
let wrapper = component.find(".top_bar");
expect(wrapper.length).toBe(1);
});
it("Should render without errors", () => {
let component = shallow(<Header />);
let logo = component.find(".fire_img");
expect(logo.length).toBe(1);
});
});
My component look:
class Header extends Component {
constructor() {
super();
this.state = {
time: undefined,
search: ""
};
}
componentDidMount() {
const { getData } = this.props;
getData();
}
render() {
const { getData, time } = this.props;
const { search } = this.state;
return (
<div className="top_bar">
{time ? (
<Countdown
key={time}
date={new Date(time)}
renderer={renderer}
onComplete={() => getData()}
/>
) : null}
<div>
<div className="search">
<h6>Enter value to filter products</h6>
<input
type="text"
value={search}
name="search"
autoComplete="off"
onChange={event => this.handleChange(event)}
/>
</div>
</div>
</div>
);
}
}
);
setupTest.js :
import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({ adapter: new Adapter() });
My package.json:
"name": "interview-question",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-scripts": "^3.1.1"
},
"dependencies": {
"babel-jest": "^24.9.0",
"date-fns": "^1.28.0",
"dayjs": "^1.8.16",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"faker": "^4.1.0",
"jest": "^24.8.0",
"jest-enzyme": "^7.1.1",
"lodash": "^4.17.15",
"node-sass": "^4.12.0",
"react": "^16.9.0",
"react-compound-timer": "^1.1.5",
"react-countdown-now": "^2.1.1",
"react-dom": "^16.9.0",
"react-loader-spinner": "^3.1.4",
"react-redux": "^7.1.0",
"react-spinners": "^0.6.1",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"styled-components": "^4.3.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
It's my first test and I don't know why test didn't work
Please help!
Thanks
Add to your package.json this config:
"jest": {
"setupFiles": [
"./path//to//your//setupTest.js"
]
}