Integrating Google Sign-In into your web app - migrating to the new library - authentication

So am practicing building this app, and I have integrated a Google sign-in using the Google Developers console. The problem is that I am getting this error on my console:
{
"error": "idpiframe_initialization_failed",
"details": "You have created a new client application that uses libraries for user authentication or authorization that will soon be deprecated. New clients must use the new libraries instead; existing clients must also migrate before these libraries are deprecated. See the Migration Guide for more information."
}
When I click the sign-in button another error then prints on my console as a second error:
{
"error": "popup_closed_by_user"
}
This is how my Login.jsx file looks like
import React from 'react';
import { GoogleLogin } from 'react-google-login';
import { useNavigate } from 'react-router-dom';
import { FcGoogle } from 'react-icons/fc';
import shareVideo from '../assets/share.mp4';
import logo from '../assets/logowhite.png';
import { client } from '../client';
const Login = () => {
const navigate = useNavigate();
const responseGoogle= (response) => {`
console.log(response)
}
return (
<div className='flex justify-start items-center flex-col h-screen'>
<div className='relative w-full h-full'>
<video
src={shareVideo}
type='video/mp4'
loop
controls={false}
muted
autoPlay
className='w-full h-full object-cover'
/>
<div className='absolute flex flex-col justify-center items-center top-0 right-0 left-0 bottom-0 bg-blackoverlay'>
<div className='p-5' >
<img src={logo} width='130px' alt='logo' />
</div>
<div className='shadow-2xl' >
<GoogleLogin
clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}
render={(renderProps) => (
<button
type='button'
className='bg-mainColor flex justify-center items-center p-3 rounded-lg cursor-pointer outline-none'
onClick={renderProps.onClick}
disabled={renderProps.disabled}
>
<FcGoogle className='mr-4' /> Sign in with Google
</button>
)}
onSuccess={responseGoogle}
onFailure={responseGoogle}
cookiePolicy='single_host_origin'
/>
</div>
</div>
</div>
</div>
)
}
export default Login
client.js
import sanityClient from '#sanity/client'
import imageUrlBuilder from '#sanity/image-url'
export const client = sanityClient({
projectId: process.env.REACT_APP_SANITY_PROJECT_ID,
dataset: 'production',
apiVersion: '2021-11-16',
useCdn: true,
token: process.env.REACT_APP_SANITY_TOKEN,
ignoreBrowserTokenWarning: true
})
const builder = imageUrlBuilder(client);
export const urlFor = (source) => builder.image(source);
App.js
import React from 'react'
import { Routes, Route, useNavigate } from 'react-router-dom';
import Login from './components/Login';
import Home from './container/Home';
const App = () => {
return (
<Routes>
<Route path="Login" element={<Login />} />
<Route path="/*" element={<Home />} />
</Routes>
)
}
export default App
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router} from 'react-router-dom'
import App from './App';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Router>
<App/>
</Router>,
);
.env
REACT_APP_GOOGLE_API_TOKEN = /*Sorry cannot show the token to you*/.apps.googleusercontent.com
REACT_APP_SANITY_PROJECT_ID = /*same here*/
REACT_APP_SANITY_TOKEN = /*same here*/
Home.jsx
import React from 'react'
const Home = () => {
return (
<div>
Home
</div>
)
}
export default Home

Related

Spotify API: Error 401, "Permissions missing"

I am trying to make use of spotify api to play songs in my webapp. I have implemented the authorization using next-auth with spotify and with the session I have pulled all my playlists to show in a list. However, when I try to play a song in that list even though I have given all the correct scopes for the PUT request and i am using a premium spotify account, it gives me this error of 401 "permissions missing".
Here is my code where I have authenticated and also given all the needed scopes.
const scopes = [
"user-read-email",
"playlist-read-private",
"playlist-read-collaborative",
"streaming",
"user-read-private",
"user-library-read",
"user-top-read",
"user-read-playback-state",
"user-modify-playback-state",
"user-read-currently-playing",
"user-read-recently-played",
"user-follow-read",
"user-library-modify",
"user-follow-modify",
"playlist-modify-public",
].join(",");
const params = {
scope: scopes,
};
const queryParamString =new URLSearchParams(params);
const LOGIN_URL = "https://accounts.spotify.com/authorize?"+ queryParamString.toString();
const spotifyApi = new SpotifyWebApi({
clientId: process.env.SPOTIFY_CLIENT_ID,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
})
export default spotifyApi;
export { LOGIN_URL };
I tried everything including reading though the spotify api docs but nothing seems to work. Here is my code which I implemented for plaing a song:
import React from 'react';
import useSpotify from '../hooks/useSpotify';
import Image from 'next/image';
import { millisToMinutes } from '../lib/time';
import { useRecoilState } from 'recoil';
import { currentTrackIdState, isPlayingState } from '../atoms/songAtom';
function Song({order, track}) {
const spotifyApi = useSpotify();
const [currentTrackId, setCurrentTrackId] = useRecoilState(currentTrackIdState);
const [isPlaying, setIsPlaying] = useRecoilState(isPlayingState);
const playSong = () => {
setCurrentTrackId(track.track.id);
setIsPlaying(true);
spotifyApi.play({
uris: [track.track.uri],
});
};
console.log(track.track.uri);
return (
<div className='grid grid-cols-2 text-gray-500 py-4 px-5 hover:bg-gray-900 rounded-md cursor-pointer'
onClick={playSong}>
<div className='flex items-center space-x-4'>
<p>{order+1}</p>
<Image alt='' src={track.track.album.images[0].url} height={40} width={40} />
<div>
<p className='w-36 lg:w-64 truncate text-white'>{track.track.name}</p>
<p className='w-40'>{track.track.artists[0].name}</p>
</div>
</div>
<div className='flex items-center justify-between ml-auto md:ml-0'>
<p className='hidden md:inline w-40'>{track.track.album.name}</p>
<p>{millisToMinutes(track.track.duration_ms)}</p>
</div>
</div>
)
}
export default Song

TypeError: Cannot read properties of undefined (reading 'map') React JS and Sanity

When I try to run the code it gives me this error=
TypeError: Cannot read properties of undefined (reading 'map')
I dont know how to solve this
import React from 'react'
import { Tweet } from '../typings'
import TweetBox from './TweetBox'
import TweetComponent from '../components/Tweet'
interface Props {
tweets: Tweet[]
}
function Feed({ tweets }: Props) {
return (
<div className='col-span-7 lg:col-span-5 border-x'>
<div className="flex items-center justify-between">
<h1 className="p-5 pb-0 text-xl font-bold">Home</h1>
<RefreshIcon className='h-8 w-8 cursor-pointer text-twitter mr-5 mt-5 transition-all duration-500 ease-out hover:rotate-180 active:scale-125'/>
</div>
<div>
<TweetBox />
</div>
{/* Feed */}
<div>
{tweets.map((tweet) => (
<TweetComponent key={tweet._id} tweet={tweet} />
))}
</div>
</div>
)
}
export default Feed ```
tweets array that you try to map is probably empty on render.
go to your index.tsx file and make sure when you are calling you feed component, you push the tweets prop through:
<Feed tweets={tweets}/>
here is the full index.tsx file below
import type { GetServerSideProps, NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
import Feed from '../components/Feed'
import Sidebar from '../components/Sidebar'
import Widgets from '../components/Widgets'
import { Tweet } from '../typings'
import { fetchTweets } from '../utils/fetchTweets'
interface Props{
tweets: Tweet[]
}
const Home = ({tweets}: Props) => {
console.log(tweets)
return (
<div className="lg:max-w-6xl mx-auto max-h-screen overflow-hidden">
<Head>
<title>Twitter 2.0</title>
</Head>
<main className='grid grid-cols-9'>
<Sidebar/>
<Feed tweets={tweets}/>
<Widgets />
</main>
</div>
)
}
export default Home
export const getServerSideProps: GetServerSideProps = async (context) => {
const tweets = await fetchTweets()
return {
props: {
tweets,
}
}
}

Why does react router work on localhost but will not work after Heroku deployment?

there are a few posts like this and I have tried other solutions such as adding a .htaccess file, and adding 'process.env.PUBLIC_URL' ahead of each route to get the relative route location, but nothing seems to be working with the new react-router-dom package which has been released...
The application will load the '/' login page no problem on startup in heroku, and in there a direct will move to another page, however after successful login I use 'window.location.assign("/Home")' to try to auto navigate back to the home page. This gets a 404 error.
Similarly, manually adding locations into the top bar also give 404 errors..
I have tried the fixes provided in other posts, but they are all for the old react-router-dom package (before they moved away from switch and started using BrowserRouter).
Can anyone help figure out why my router won't identify addresses added to the window location??
The application is currently deployed at https://dashboard.heroku.com/apps/octowatch-scratch
App.js
import React from "react";
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import AboutKPI from './pages/AboutKPI';
import Login from './pages/Login';
import BreachComposition from './pages/BreachComposition';
import BreachesPerWard from './pages/BreachesPerWard';
import Dashboard from './pages/Dashboard';
import AddAccount from './pages/AddAccount';
import ManageAccounts from './pages/ManageAccounts';
import OverallBreaches from './pages/OverallBreaches';
import AddData from './pages/AddData';
import Home from './pages/Home';
import { lightGreen, brown } from '#mui/material/colors';
import './App.css';
const theme = createTheme({
palette: {
primary: {main: lightGreen[900]},
secondary: {main: brown[500]},
},
});
function App() {
return (
<BrowserRouter>
<ThemeProvider theme={theme}>
<Routes>
<Route exact path="/" element = {<Login/>} />
<Route exact path="/AboutKPI" element = {<AboutKPI/>} />
<Route exact path="/BreachComposition" element = {<BreachComposition/>} />
<Route exact path="/BreachesPerWard" element = {<BreachesPerWard/>} />
<Route exact path="/Login" element = {<Login/>} />
<Route exact path="/Home" element = {<Home/>} />
<Route exact path="/Dashboard" element = {<Dashboard/>} />
<Route exact path="/AddAccount" element = {<AddAccount/>} />
<Route exact path="/ManageAccounts" element = {<ManageAccounts/>} />
<Route exact path="/OverallBreaches" element = {<OverallBreaches/>} />
<Route exact path="/AddData" element = {<AddData/>} />
</Routes>
</ThemeProvider>
</BrowserRouter>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Login Page ()
import React, { useState } from "react";
import { Grid,Paper, Avatar, TextField, Button, Typography } from '#mui/material'
import FormControlLabel from '#mui/material/FormControlLabel';
import Checkbox from '#mui/material/Checkbox';
import Api from "../api.js"
import LockIcon from '#mui/icons-material/Lock';
import { Link } from 'react-router-dom';
export default function Login(breachesCallback) {
const paperStyle={padding :20,height:'70vh',width:280, margin:"20px auto"}
const avatarStyle={backgroundColor:'#1bbd7e'}
const btnstyle={margin:'8px 0'}
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
var now = new Date();
function validateForm() {
return email.length > 0 && password.length > 0;
}
function goHome () {
window.location.assign("/Home");
}
function goReset () {
window.location.assign("/UpdatePassword");
}
function handleSubmit(event) {
Api.noToken().post('/users/login', {
email: email,
password: password,
resetDate: Math.floor(((now / 8.64e7) - 150.604166666))
})
.then(function (response) {
if(response.status === 204){//this means a password reset still needs to occur here
Api.withToken().get('/breaches/')
.then(res => {
breachesCallback(res.data);
console.log(res.data);
}).then(goReset());
}
else if(response.status === 200){
window.sessionStorage.setItem("token", response.data.token);
Api.withToken().get('/breaches/')
.then(res => {
breachesCallback(res.data);
console.log(res.data);
}).then(goHome());
}
})
.catch(function (error) {
alert("Invalid username or password")
});
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<Grid>
<Paper elevation={10} style={paperStyle}>
<Grid align='center'>
<Avatar style={avatarStyle}><LockIcon/></Avatar>
<h2>Sign In</h2>
</Grid>
<TextField label='Username' placeholder='Enter username' fullWidth required onChange={e => setEmail(e.target.value)}/>
<TextField label='Password' placeholder='Enter password' type='password' fullWidth required onChange={e => setPassword(e.target.value)}/>
<FormControlLabel
control={
<Checkbox
name="checkedB"
color="primary"
/>
}
label="Remember me"
/>
<Button type='submit' disabled={!validateForm()} color='primary' variant="contained" style={btnstyle} fullWidth>Sign in</Button>
<Typography >
<Link to="#" >
Forgot password ?
</Link>
</Typography>
<Typography > Do you have an account ?
<Link to="/AddAccount" >
Sign Up
</Link>
</Typography>
</Paper>
</Grid>
</form>
)
}
After hours of looking I've finally found the most up to date tool you are meant to use for react router in the latest update (currently 6.1.1)
This is about 3 posts down in this post (the other answers are all for older versions of react router and will not work)
The answer is simple:
import { useNavigate } from "react-router-dom";
then in your function add a simpler variable for useNavigate:
let navigate = useNavigate();
and replace your window.location.assign("/Home") with navigate("/Home", { replace: true });
(obviously could also just say useNavigate("/Home", {replace:true})

Attempted import error: 'signInUserWithEmailAndPassword' is not exported from 'firebase/auth'

please i need your help
I'm using Firebase 9.02 and i'm facing a problem when i try to import signInUserWithEmailAndPassword to sign in my users with Firebase authentication module
Is it a problem in the version 9 of Firebase ?
Thank you in advance
import React, { useRef } from "react";
import "./SignUpScreen.css";
import auth from "../firebase";
import {
createUserWithEmailAndPassword,
signInUserWithEmailAndPassword,
} from "firebase/auth";
// import auth from "../firebase";
const SignUpScreen = () => {
const emailRef = useRef(null);
const passwordRef = useRef(null);
const signIn = (e) => {
e.preventDefault();
signInUserWithEmailAndPassword(auth, emailRef, passwordRef)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
})
.catch((error) => {
alert(error);
});
};
return (
<div className='signupScreen'>
<form>
<h1>Sign In</h1>
<input
ref={emailRef}
className='signin'
type='email'
placeholder='Email'
/>
<input
ref={passwordRef}
className='signin'
type='password'
placeholder='Password'
/>
<button onClick={signIn} className='signin' type='submit'>
Sign In
</button>
</form>
</div>
);
};
export default SignUpScreen;```
No, the error is not a problem with version 9 of the Firebase SDK.
The issue is that the method is wrongly spelt.
It's signInWithEmailAndPassword and not signInUserWithEmailAndPassword.
Checkout the documentation

Meteor authentication and react-router

How do I get meteor to re-render my components when I sign in using the accounts-password package?
My react-router routes are:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
import App from './containers/App'
import Recordings from './containers/Recordings'
import LandingPage from './containers/LandingPage'
import { BloodPressure } from '../collections/BloodPressure'
const routes = (
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={LandingPage} />
<Route path="dashboard" component={Recordings} />
</Route>
</Router>
)
Meteor.startup( ()=> {
ReactDOM.render(routes, document.querySelector('.render-target'))
})
My App component is:
import React, { Component } from 'react'
import { createContainer } from 'meteor/react-meteor-data'
import { browserHistory } from 'react-router'
import Header from './Header'
class App extends Component {
constructor(props) {
super(props)
}
render() {
return(
<div>
<div className="ui four container">
<Header />
{this.props.children}
</div>
<div className="footer">
<p>Designed and Developed by Thomas Hoadley</p>
</div>
</div>
)
}
}
export default createContainer(() => {
return {
signedIn: Meteor.userId()
}
}, App)
When I sign in, I expect the page to automatically reload with the correct routes, however I am having to reload the page manually to redirect it.
Any help on this issue would be greatly appreciated!