const navigate = useNavigate();
const responseGoogle = (response) => {
localStorage.setItem('user', JSON.stringify(response.profileObj));
const { name, googleId, imageUrl } = response.profileObj;
const doc = {
_id: googleId,
_type: 'user',
userName: name,
image: imageUrl,
};
client.createIfNotExists(doc).then(() => {
navigate('/', { replace: true });
});
};
我收到“名称未定义”的错误 – 但怎么办?
imageUrl
和 googleId
工作正常,那么 name
有什么问题吗?
我猜你和我一样正在从事 (https://www.youtube.com/watch?v=XxXyfkrP298&t=3800s) 的 ShareMe 项目。
登录已更新,现在 Google 服务在响应中返回一组与录制视频时返回的参数不同的参数。
您正在寻找的参数(例如“name”和“id”)现在可以在response.credential中找到,但它已被编码(出于安全原因),现在您必须对其进行解码。您必须使用“npm i jwt-decode”() 在“shareme_frontend”文件夹中安装“jwt-decode”,并且您将能够使用“var generatedHeader = jwt_decode(response.credential);”对其进行解码,您应该能够使用属性“名称”、“子”(而不是 ID)和“图片”,这应该可以帮助您加快速度。
您遇到的问题是名称未定义,因为没有response.name,只有response.credential.name并且需要解码。因此,这可能会非常令人沮丧,但当您打印回复时您会看到问题。
来源:
我的例子:
import jwt_decode from "jwt-decode";
const responseGoogle=(response)=>{
localStorage.setItem('user', JSON.stringify(response.profileObj));
var decodedHeader = jwt_decode(response.credential);
console.log(decodedHeader);
const { name, sub, picture } = decodedHeader;
const doc = {
_id: sub,
_type: 'user',
userName: name,
image: picture,
}
client.createIfNotExists(doc)
.then(() =>{
navigate('/', { replace: true })
})
}
这可能是一个符号问题,请尝试这个:
const navigate = useNavigate();
const responseGoogle = (response) => {
localStorage.setItem('user', JSON.stringify(response.profileObj));
const doc = {
_id: response.profileObj.googleId,
_type: 'user',
userName: response.profileObj.name,
image: response.profileObj.imageUrl,
};
client.createIfNotExists(doc).then(() => {
navigate('/', { replace: true });
});
};
更新:React 更新了他们的登录方法,所以你需要搜索最新的 google 登录方法
尝试添加
npm install gapi-script
然后像这样添加useEffect函数
useEffect(() => {
function start() {
gapi.client.init({
ClientId: process.env.REACT_APP_GOOGLE_API_TOKEN,
scope: '',
})
}
gapi.load('client:auth2', start)})
我遇到了同样的问题,同样的问题,这是shareme项目吗?我认为 googleId 和 imageUrl 也不起作用。您可以像这样切换这三个的顺序
const { imageUrl,name, googleId } = response.profileObj;
它会给你错误: cb=gapi.loaded_0?le=scs:225 未捕获类型错误:无法解构“response.profileObj”的属性“imageUrl”,因为它未定义。
所以我也卡在这里寻求帮助!
这个问题已经过去很长时间了,但我找到了一个对我有用的解决方案,我以这种方式对呼叫进行了更改
const navigate = useNavigate();
const responseGoogle = (response) => {
localStorage.setItem('user', JSON.stringify(response));
const { clientId, name, imageUrl } = response;
const doc = {
_id: clientId,
_type: 'user',
userName: name,
image: imageUrl,
};
client.createIfNotExists(doc).then(() => {
navigate('/', { replace: true });
});
};
我还更改了谷歌按钮库,使用了@react-oauth/google,按钮看起来像这样:
<GoogleLogin
onSuccess={responseGoogle}
onError={responseGoogle}/>
我已经解决这个问题有一段时间了,结果发现同一件事有不同的方法。(React 不断更新谷歌登录方法,因此需要更新的方法), 在响应对象中存在凭证属性,它需要通过 jwt_decode 函数进行解码,该函数可以从库“jwt-decode”中导入,可以进一步提取详细信息。
const responseGoogle = (response) =>{
console.log(response);
var profileObj = jwt_decode(response.credential);
console.log(profileObj);
const doc = {
_id: profileObj.sub,
_type: "user",
userName: profileObj.name,
image: profileObj.picture,
};
client.createIfNotExists(doc)
.then(()=>{
console.log('Login Created')
});
代码应该如下所示:
import jwt_decode from "jwt-decode";
const responseGoogle = (response) =>{
console.log(response);
var profileObj = jwt_decode(response.credential);
console.log(profileObj);
const doc = {
_id: profileObj.sub,
_type: "user",
userName: profileObj.name,
image: profileObj.picture
};
console.log(doc)
client.createIfNotExists(doc)
.then(()=>{
navigate("/", { replace: true });
console.log('Login Created')
});
}
有新更新,我们使用 Google Identity Services SDK 检查此链接 https://www.npmjs.com/package/@react-oauth/google .
尝试使用此代码登录并获取用户信息。
登录.jsx:
import React from 'react'
import { GoogleOAuthProvider } from '@react-oauth/google';
import { GoogleLogin, googleLogout } from '@react-oauth/google';
import { useNavigate } from 'react-router-dom';
import {FcGoogle} from 'react-icons/fc' ;
import shareVideo from '../assets/share.mp4' ;
import logo from '../assets/mejlis-logo.png' ;
import {client} from '../client';
import jwt_decode from "jwt-decode";
//import JWT from 'google-auth-library';
const Login = () => {
const navigate = useNavigate();
const responseGoogle = async(response) => {
localStorage.setItem('user', JSON.stringify(response));
console.log(response);
const decoded = jwt_decode(response.credential)
const { sub, name, picture } = decoded;
const doc = {
_id: sub,
_type: 'user',
userName: name,
image: picture,
};
client.createIfNotExists(doc).then(() => {
navigate('/', { replace: true });
});
};
return (
<div className='flex justify-start items-center flex-col h-screen'>
<div className='relativr w-full h-full'>
<video src ={shareVideo} type ='video/mp4'
loop
controls={false}
muted
autoPlay
className='w-full h-full object-cover' />
</div>
<div className='absolute flex flex-col justify-center items-center top-0 right- left-0 bottom-0 bg-blackOverlay'>
<div className='p=5'>
<img src={logo} width="130px" alt='logo'/>
</div>
<div className='shadow-2x1'>
<GoogleOAuthProvider
clientId={`${process.env.REACT_APP_GOOGLE_API_TOKEN}`}>
<GoogleLogin
onSuccess={responseGoogle}
onFailure={responseGoogle}
cookiePolicy = 'single_host_origin' />
</GoogleOAuthProvider>
</div>
</div>
</div>
)
}
export default Login
为谷歌创建的问题更新了他们的谷歌登录设置。您可以在安装最新的 Google OAuth 后尝试此代码:
const navigate = useNavigate();
const responseGoogle = (response) => {
const decoded = jwt_decode(response.credential);
console.log(decoded);
const { name, picture, sub } = decoded;
const user = {
_id: sub,
_type: 'user',
userName: name,
image: picture
};
client.createIfNotExists(user)
.then(()=>{
navigate('/', { replace: true });
});
}
正如许多人在我之前指出的那样,发生此错误的原因不仅是由于 Google 新响应中的结构不同,而且还因为教程视频中建议的用于 Google Login 的 React 库已被弃用。这是解决问题的最新方法:
首先,更新您用于 Google 登录的库。为此,请在终端中运行:
npm uninstall react-google-login
然后,安装当前最新的库React OAuth2 |谷歌。按照其 npm 页面上的步骤(请参阅前面的链接)安装此库。在本教程的特定情况下,步骤如下:
(1)安装新库
npm install @react-oauth/google@latest
(2) 使用 GoogleOAuthProvider 包装您的应用程序。你的 App.js 文件应该看起来像这样:
import React from "react";
import { Routes, Route, useNavigate } from "react-router-dom";
import { GoogleOAuthProvider } from "@react-oauth/google";
import Login from "./components/Login";
import Home from "./container/Home";
const App = () => {
return (
<GoogleOAuthProvider clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}>
<Routes>
<Route path="login" element={<Login />} />
<Route path="/*" element={<Home />} />
</Routes>
</GoogleOAuthProvider>
);
};
export default App;
(3) 更改 Login.jsx 文件中的代码,以反映所用库的更改和响应结构的更改。它应该看起来有点像这样:
import { GoogleLogin } from "@react-oauth/google";
const responseGoogle = (response) => {
localStorage.setItem("user", JSON.stringify(response.profileObj));
const decodedHeader = jwt_decode(response.credential);
const { name, sub, picture } = decodedHeader;
const doc = {
_id: sub,
_type: "user",
userName: name,
image: picture,
};
client.createIfNotExists(doc).then(() => {
navigate("/", { replace: true });
});
};
对于响应或所使用的库的未来更改,请尝试控制台记录 Google 响应本身。就我而言,这些错误非常准确地告诉我如何修复错误。
我注意到使用“aud”无法正常工作。相反,使用 sub 来正确传递不同的 googleID。
这是我的源代码至少。
import React from 'react'
// import GoogleLogin from 'react-google-login'
import { GoogleOAuthProvider } from '@react-oauth/google';
import { GoogleLogin, googleLogout } from '@react-oauth/google'
import jwt_decode from 'jwt-decode';
import { useNavigate } from 'react-router-dom'
import shareVideo from '../assets/share.mp4'
import logo from '../assets/LogoSWhite2.png'
import {client} from '../client'
const Login = () => {
// const responseGoogle = (response) => {
// console.log(response);
// }
const navigate = useNavigate();
const responseGoogle = (response) => {
const decode = jwt_decode(response.credential);
console.log(decode);
localStorage.setItem('user', JSON.stringify(decode));
const { name, sub, picture } = decode;
const doc = {
_id: sub,
_type: 'user',
userName: name,
image: picture,
}
console.log("googleId:", sub);
console.log("image:", picture);
client.createIfNotExists(doc)
.then(() => {
navigate('/', {replace: true})
})
}
return (
<div className="flex justiy-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'>
<GoogleOAuthProvider clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}>
<GoogleLogin
onSuccess={responseGoogle}
onFailure={responseGoogle}
cookiePolicy="single_host_origin"
/>
</GoogleOAuthProvider>
{/* <GoogleOAuthProvider
clientId={process.env.REACT_APP_GOOGLE_API_TOKEN}>
<GoogleLogin
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"
/>;
</GoogleOAuthProvider>; */}
</div>
</div>
</div>
</div>
)
}
export default Login