使用 firebase 验证用户身份并做出反应。

2025-06-07

使用 firebase 验证用户身份并做出反应。

在本文中,我们将使用 Firebase 进行基本的用户身份验证。如果您有其他类型的用户身份验证经验,您可能会感到沮丧。

Firebase 确实有一个学习曲线,但与其他替代方案相比,我发现它的学习曲线较小。

Firebase 将承担许多繁重的后端功能

如果你想看看这个应用程序的功能,这里是“完成”的产品,你可以在这里

本教程为何有用?

这就是如何利用 firebase,这样您就不必创建自己的后端、加密用户密码或经历部署后端应用程序的麻烦。

先决条件:

  1. 了解 JavaScript,包括如何将参数传递给函数和异步代码。

  2. 了解 react、context、hooks 与create-react-app

  3. 您选择的文本编辑器。(我将使用vscode

  4. Firebase 帐户

  5. 对命令行有基本的了解。

  6. git 知识。

可选:bash 命令行/Mac OS。您可以不用它,但在本教程中我会使用它。

首先,访问https://firebase.com创建一个新的 firebase 项目。

替代文本

单击一个新项目。

替代文本

单击“我的第一个项目”,然后您可以随意命名您的项目。

单击继续。

替代文本

您可以选择不使用 Google Analytics,它不会干扰本教程,我将其保留,因此您将看到启用它的部分代码。

单击继续。

替代文本

系统将提示您选择一个帐户。

替代文本

选择默认帐户,然后单击创建项目。

替代文本

您现在应该可以看到这一点。

替代文本

您应该在 Firebase 控制台中执行此项目。

替代文本

点击左侧导航上的身份验证。

替代文本

点击设置登录方式。

替代文本

有很多方法可以设置用户登录我们的应用。在本教程中,我们将使用最简单的方法。

点击电子邮件和密码。

替代文本

单击启用。

替代文本

节省。

确保它确实已启用。

替代文本

现在转到项目概述。

替代文本

我们需要获取有关我们的应用如何发送和接收 Firebase 数据的信息,因此我们必须获取以 SDK 形式提供给我们的 API 密钥和其他敏感信息。

单击括号即可开始。

![替代文本]( https://dev-to-uploads.s3.amazonaws.com/i/zzpeg5dqj7qmlewy87h9 ..

我们将创建一个 React 应用程序并将脚本标签内的所有内容添加到 React 项目中。

替代文本

由于我们还没有 firebaseIndex.js,所以我们还不能添加它。

这就是我们在 Firebase 控制台上为我们的项目所要做的所有事情。

创建一个新的反应应用程序。

create-react-app firebaseauthtutorial 
Enter fullscreen mode Exit fullscreen mode

cd 应用程序

cd firebaseauthtutorial
Enter fullscreen mode Exit fullscreen mode

这是一个规划所需软件包类型的好时机。这些都将通过 npm 安装。

  1. firebase。如果这是一个普通的 javascript,我们将使用整个脚本和 SKD。

  2. react-router-dom

这样,当用户登录时,我们会显示只有用户可访问的组件。

  1. dotenv,在制作包含用户数据或利用 API 的应用程序(就像这个应用程序一样)时,最好的习惯是确保黑客无法访问您的 API 密钥、加密技术或其他用户的敏感信息。

dotenv 允许您将敏感信息保存为环境范围变量,这样您就无法发布到远程存储库,但仍可以在您的应用程序中使用。

在命令行上运行 npm install 来安装所有软件包

专业提示:在运行 npm install 之前,请确保您位于项目的根目录中

npm install firebase dotenv react-router-dom
Enter fullscreen mode Exit fullscreen mode

现在打开项目。

我正在使用 vscode,所以这是从命令行执行的操作。

code .
Enter fullscreen mode Exit fullscreen mode

查看 package.json 文件,您应该会看到您安装的包。

替代文本
包.json

在应用程序中移动 SDK firebase。

在将 SDK 复制粘贴到我们的文件之前,最好将 .env 文件添加到 .gitignore 中,这样就不会将环境变量发布到 GitHub。很容易忘记。

然后将 API 密钥添加到 .env

然后从我们即将创建的 firebaseIndex.js 中引用它们到 .env 文件中。

这样,在学习本教程时,您就不会面临泄露密钥的危险。

点击你的 .gitignore

替代文本

在文件中的任何位置写入 .env

替代文本

然后右键单击根目录中的空白处。(如果没有,您可以最小化轮廓以显示空间。)

替代文本

替代文本

将以下变量复制并粘贴到 .env 文件中

REACT_APP_API_KEY=

REACT_APP_AUTHDOMAIN=

REACT_APP_BASEURL=

REACT_APP_PROJECT_ID=

REACT_APP_STORAGEBUCKET=

REACT_APP_MESSAGING_SENDER_ID=

REACT_APP_APP_ID=

REACT_APP_MEASUREMENT_ID=
Enter fullscreen mode Exit fullscreen mode

包括引号在内,从 SDK 中逐一复制并粘贴信息。API 密钥、授权域、baseurl 等……

你应该有这样的东西。

来自 firebase 的信息。

REACT_APP_API_KEY="your secret api key"
REACT_APP_AUTHDOMAIN="your secret authdomain"
REACT_APP_BASEURL="your secret baseurl"
REACT_APP_PROJECT_ID="your secret projectid"
REACT_APP_STORAGEBUCKET="your secret storeagebucket"
REACT_APP_MESSAGING_SENDER_ID="your secret messaging sender id"
REACT_APP_APP_ID="your secret app id"
REACT_APP_MEASUREMENT_ID="your secret measurment id"

Enter fullscreen mode Exit fullscreen mode

现在是简单的部分。

首先创建文件夹来保存 firebases SDK 和用于身份验证的辅助方法。

尝试从文本编辑器中执行此操作。

右键单击 src 文件夹,然后单击新建文件夹。

替代文本

将文件夹命名为 firebase。

替代文本

现在右键单击 firebase 文件夹并添加 firebaseIndex.js

替代文本

firebaseIndex.js

替代文本

在 firebaseIndex.js 文件的顶部导入 firebase 以及您想要的功能。

import firebase from 'firebase'
import 'firebase/auth'
import 'firebase/app'
Enter fullscreen mode Exit fullscreen mode

现在您的环境变量已在应用程序范围内设置,您可以复制并粘贴此 SDK,使用我提供的代码在 firebaseIndex 文件中引用您的敏感数据。

var firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTHDOMAIN,
  databaseURL: process.env.REACT_APP_BASEURL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
  measurementId: process.env.REACT_APP_MEASUREMENT_ID
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();

Enter fullscreen mode Exit fullscreen mode

在 analytics() 方法下添加 firebase.auth() 辅助方法。


firebase.auth()
Enter fullscreen mode Exit fullscreen mode

我们需要另一个文件中的 firebaseConfig 对象,因此需要将其导出

export default {
  firebaseConfig, 
}
Enter fullscreen mode Exit fullscreen mode

整个文件应该看起来像这样。



import firebase from 'firebase'
import 'firebase/auth'
import 'firebase/app'

var firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTHDOMAIN,
  databaseURL: process.env.REACT_APP_BASEURL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGEBUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
  measurementId: process.env.REACT_APP_MEASUREMENT_ID
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
firebase.auth()

export default {
  firebaseConfig, 
}

Enter fullscreen mode Exit fullscreen mode

如果您按照这些步骤操作,您可以随时推送到 github,并且它不会保存您的密钥。

添加身份验证方法。

在您的 firebase 文件夹中创建一个名为 auth methods 的文件,这是保存包含 signin、signup、signout 功能的对象的地方。

替代文本

替代文本

在顶部导入两样东西,firebaseConfig 对象和来自 firebase 的 firebase,像这样。

import firebaseconfig from './firebaseIndex'
import firebase from 'firebase'
Enter fullscreen mode Exit fullscreen mode

现在进行导出并创建一个身份验证方法对象。

export const authMethods = {

// firebase helper methods go here... 

}
Enter fullscreen mode Exit fullscreen mode

我们将把它发送到上下文中,它将成为链接到登录表单的一系列方法的顶部。

替代文本

这些将是键/值对,我们为其提供用于登录的匿名函数。


 export const authMethods = {
  // firebase helper methods go here... 
  signup: (email, password) => {

    },
  signin: (email, password) => {

    },
  signout: (email, password) => {

    },
  }
Enter fullscreen mode Exit fullscreen mode

我第一次看到它的时候,感觉很不寻常。等我们结合上下文再来理解它,就会明白很多了。

这是来自用户身份验证的 firebase 文档

signup: (email, password) => {
    firebase.auth().createUserWithEmailAndPassword(email,password) 
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.error(err)
      })
    },
Enter fullscreen mode Exit fullscreen mode

在开始添加其他方法之前,我想测试一下这段代码是否有效。

为此,请构建上下文和注册表单,然后查看 Firebase 是否会响应。

为我们的应用程序创建上下文。

右键单击 src 文件夹并创建一个名为 provider 的新文件夹。

替代文本

替代文本

右键单击提供程序并创建一个名为 AuthProvider.js 的文件

替代文本

替代文本

制作一个功能组件,添加道具。

import React from 'react';

const AuthProvider = (props) => {
  return (
    <div>

    </div>
  );
};

export default AuthProvider;

Enter fullscreen mode Exit fullscreen mode

在函数外部,创建一个 firebaseAuth 变量并使其等于反应上下文。

export const firebaseAuth = React.createContext()
Enter fullscreen mode Exit fullscreen mode

我们必须导出它以便我们可以访问 useContext 钩子。

删除 div 标签并使提供程序位于 AuthProvider 的返回内部,我不会解释这里发生的所有事情,但如果您想了解有关上下文的更多信息,这是一篇我解释上下文和 useContext 钩子的文章。

const AuthProvider = (props) => {
  return (
    <firebaseAuth.Provider
    value={{
      test: "context is working"
    }}>
      {props.children}

    </firebaseAuth.Provider>
  );
};
Enter fullscreen mode Exit fullscreen mode

AuthProvider.js

现在我们需要将 App.js 包装在 index.js 文件中的 AuthProvider 组件中。

我们还需要导入动态路由组件的能力,因为我们已经在这个文件中,从 react-router-dom 添加 BrowserRouter。

首先在顶部导入 AuthProvider 和 BrowserRouter。

import AuthProvider from './provider/AuthProvider'
import {BrowserRouter} from 'react-router-dom'
Enter fullscreen mode Exit fullscreen mode

然后用 BrowserRouter 和 AuthProvider 制作一个 App 三明治。

ReactDOM.render(
<BrowserRouter>
  <AuthProvider>
    <App />
  </AuthProvider>
</BrowserRouter>
, document.getElementById('root'));
Enter fullscreen mode Exit fullscreen mode

两件事,

转到 App.js,在顶部更改 React 的导入方式以包含 useContext 和 React。

导入 {firebaseAuth} 以便我们可以像这样从中解构测试键/值对。

import React, {useContext} from 'react';
import {firebaseAuth} from './provider/AuthProvider'
Enter fullscreen mode Exit fullscreen mode

在函数解构测试中从 firebaseAuth 变量进行测试。

console.log 测试。

   const {test} = useContext(firebaseAuth)
    console.log(test)

Enter fullscreen mode Exit fullscreen mode

返回终端并启动服务器。

npm start
Enter fullscreen mode Exit fullscreen mode

使用开发工具检查你应该会看到这一点。

替代文本

连接到 authMethods

现在我们有了 App 范围的上下文,返回 AuthProvider.js 并导入 authMethods。

import {authMethods} from '../firebase/authmethods'
Enter fullscreen mode Exit fullscreen mode

该文件是 Firebase 和我们即将制作的 Signup 组件之间的中间人,

这意味着所有状态逻辑都将存放在这里。

在 AuthProvider 内部创建一个名为 handleSignup 的函数。

const handleSignup = () => {
    // middle man between firebase and signup 

  }
Enter fullscreen mode Exit fullscreen mode

将其作为 firebaseAuth.Provider 中的值传递

 <firebaseAuth.Provider
    value={{
      //replaced test with handleSignup
      handleSignup
    }}>
      {props.children}

    </firebaseAuth.Provider>

Enter fullscreen mode Exit fullscreen mode

现在在 App.js 中使用 handleSignup 更改测试

 const {handleSignup} = useContext(firebaseAuth)
    console.log(handleSignup)

Enter fullscreen mode Exit fullscreen mode

App.js

你应该看到

替代文本

在 AuthProvider 中,将 authMethod.signup() 添加到 handleSignup。

  const handleSignup = () => {
    // middle man between firebase and signup 
    console.log('handleSignup')
    // calling signup from firebase server
    return authMethods.signup()
  }
Enter fullscreen mode Exit fullscreen mode

创建一个组件文件夹和 Signup.js 组件,在我们希望它最终出现的位置重新创建相同的功能,以便我们可以在 App.js 中定义我们的路由

替代文本

替代文本

制作 Signup.js

替代文本

替代文本

制作一个基本组件


// add useContext
import React, {useContext} from 'react';

const Signup = () => {


  return (
    <div>
      Signup
    </div>
  );
};

export default Signup;
Enter fullscreen mode Exit fullscreen mode

像在 App.js 中一样,从上下文中解构 handleSignup 函数

const {handleSignup} = useContext(firebaseAuth)
    console.log(handleSignup)
Enter fullscreen mode Exit fullscreen mode

__

在 App.js 中,通过删除样板并添加 Switch 和 Route 来添加 react-router-dom 的开头,设置由 Route 呈现的注册。


import {Route, Switch} from 'react-router-dom'
import Signup from './component/Signup'
Enter fullscreen mode Exit fullscreen mode

App.js

 return (
    <>
    {/* switch allows switching which components render.  */}
      <Switch>
        {/* route allows you to render by url path */}
        <Route exact path='/' component={Signup} />

      </Switch>
    </>
  );
Enter fullscreen mode Exit fullscreen mode

如果一切顺利,您应该会看到一个带有注册信息的白色屏幕。

替代文本

制作一个注册表。

return (
    <form>
      {/* replace the div tags with a form tag */}
      Signup
      {/* make inputs  */}
      <inputs  />
      <button>signup</button>
    </form>
  );
Enter fullscreen mode Exit fullscreen mode

此时,可能很想在这里建立状态。但我们希望上下文成为唯一的事实来源,以便如果用户在登录和注册之间切换,他们输入的任何内容都将保留下来。

返回 AuthProvider 并开始设置状态。

我们需要来自 Firebase 的令牌和用户数据的状态。

在 React 旁边导入 useState。

import React, {useState} from 'react';
Enter fullscreen mode Exit fullscreen mode

AuthProvider.js

我们想要的状态将会实现。

  1. token 为 null (一旦我们从 firebase 获取 token 则为字符串),有关json web token 的更多信息。

  2. 输入为包含电子邮件和密码两个字符串的对象。

  3. 错误作为数组,以便可以向用户显示错误消息。

将这些状态添加到 AuthProvider.js


const [inputs, setInputs] = useState({email: '', password: ''})
  const [errors, setErrors] = useState([])
  const [token, setToken] = useState(null)

Enter fullscreen mode Exit fullscreen mode

将输入添加到提供者的值对象。

<firebaseAuth.Provider
    value={{
      //replaced test with handleSignup
      handleSignup,
      inputs,
      setInputs,

    }}>

Enter fullscreen mode Exit fullscreen mode

在 Signup.js 中,使用 useContext 钩子从 authContext 获取它们,如下所示。

  const {handleSignup, inputs, setInputs} = useContext(firebaseAuth)
Enter fullscreen mode Exit fullscreen mode

将 handleChange 和 handleSubmit 函数作为基本形式。

const handleSubmit = (e) => {
    e.preventDefault()
    console.log('handleSubmit')

  }
  const handleChange = e => {
    const {name, value} = e.target
    console.log(inputs)
    setInputs(prev => ({...prev, [name]: value}))
  }
Enter fullscreen mode Exit fullscreen mode

更改表单和输入字段以使用表单功能。

<form onSubmit={handleSubmit}>
      {/* replace the div tags with a form tag */}
      Signup
      {/* make inputs  */}
      <input onChange={handleChange} name="email" placeholder='email' value={inputs.email} />
      <input onChange={handleChange} name="password" placeholder='password' value={inputs.password} />
      <button>signup</button>
    </form>

Enter fullscreen mode Exit fullscreen mode

如果您正确地完成了所有操作并运行了如下测试...

替代文本

这是您可能收到的错误消息。

替代文本

我们收到此错误的原因是我们没有向 authMethods.signup 传递它期望的电子邮件和密码参数。

将inputs.email和inputs.password传递到authMethods.signin

authMethods.signup(inputs.email, inputs.password)
Enter fullscreen mode Exit fullscreen mode

当你做这样的测试时。

替代文本

你应该会得到这样的回应。

替代文本

但如果你尝试执行两次,就会出现错误。

替代文本

这是因为您不能重复此操作。所有电子邮件都必须是唯一的。

为了使错误消息显示给用户,我们必须执行以下操作。

  1. 在 AuthProvider.js 中,将 setErrors 作为参数与电子邮件和密码一起传递,

这是我能想出的唯一方法。每当你必须向函数传递多个参数时,你都应该有一个很好的理由。

  1. 在 authMethods.js 的 signup() 中,在顶部添加第三个参数,并在 .catch 中,我们将错误消息保存到错误数组中。

  2. 通过将错误传递给 Signup.js 并通过数组映射,将错误显示到屏幕上。

1.

//sending setErrors
  authMethods.signup(inputs.email, inputs.password, setErrors)
console.log(errors)
Enter fullscreen mode Exit fullscreen mode

现在添加 setErrors 消息以及电子邮件和密码。

AuthProvider.js
2.

  //catching setErrors
 signup: (email, password, setErrors) => {
Enter fullscreen mode Exit fullscreen mode

authMethods.js

如果出现多个错误,请将 catch 更改为 setErrors 包括 prev

.catch(err => {
       //saving error messages here
        setErrors(prev => ([...prev, err.message]))
      })

Enter fullscreen mode Exit fullscreen mode

如果它起作用并且您在控制台记录了它,您应该会看到这个错误。

替代文本

  1. 将错误添加到 Provider 的值对象中
 <firebaseAuth.Provider
    value={{
      //replaced test with handleSignup
      handleSignup,
      inputs,
      setInputs,
//added errors to send to Signup.js
      errors,
    }}>
      {props.children}
    </firebaseAuth.Provider>

Enter fullscreen mode Exit fullscreen mode

AuthProvider.js

从 Signup.js 中的 useContext 中解构它

const {handleSignup, inputs, setInputs, errors} = useContext(firebaseAuth)

Enter fullscreen mode Exit fullscreen mode

Signup.js

现在添加一个三元组,只有发生错误时才会显示。

  <button>signup</button>
      {errors.length > 0 ? errors.map(error => <p style={{color: 'red'}}>{error}</p> ) : null}
    </form>
Enter fullscreen mode Exit fullscreen mode

如果一切正常,您将在屏幕上看到错误。

替代文本

如果您想过滤重复项,您可以找出或看看我在 repo 上的表现,但本教程很长,还有一些事情要做。

这样您就可以为每个帐户启用多个电子邮件。

进入该项目内的firebase,单击身份验证。

点击登录方法

滚动到底部,那里用黑色小字母写着“高级”。它用粗体字写着“每个电子邮件一个帐户”。

点击蓝色的更改按钮

替代文本

单击允许使用同一电子邮件的多个帐户。

这将帮助我们更快地进行测试,但不要忘记稍后将其切换回来。

  1. 与我们设置错误的方式相同,我们将把令牌保存到 localStorage,并将令牌的状态保存在 AuthProvider 中。

  2. 使得我们只有拥有令牌才能看到某些组件。

  3. 如果本地存储中的令牌与状态中的令牌匹配,则重定向到该页面。

  4. 重复该过程以进行登录。

  5. 使用登录方法擦除令牌并将用户推出我们应用程序的经过身份验证的部分。

  6. 转到 AuthProvider.js 并在 setErrors 之后添加 setToken 作为另一个参数。

//sending setToken function to authMethods.js
 authMethods.signup(inputs.email, inputs.password, setErrors, setToken)
    console.log(errors, token)
Enter fullscreen mode Exit fullscreen mode

AuthProvider.js

将其作为第四个参数添加到顶部。

// added the 4th argument
 signup: (email, password, setErrors, setToken) => {
Enter fullscreen mode Exit fullscreen mode

在 .then 里面,在 console.log(res) 下面...

我将为您节省大量时间,您无需花费大量时间挖掘 res 对象来查找令牌。

这也会使异步代码变得有点混乱。

signup: (email, password, setErrors, setToken) => {
    firebase.auth().createUserWithEmailAndPassword(email,password) 
      //make res asynchronous so that we can make grab the token before saving it.
      .then( async res => {
        const token = await Object.entries(res.user)[5][1].b
          //set token to localStorage 
          await localStorage.setItem('token', token)
          //grab token from local storage and set to state. 
          setToken(window.localStorage.token)
        console.log(res)
      })
      .catch(err => {
        setErrors(prev => ([...prev, err.message]))
      })
    },
Enter fullscreen mode Exit fullscreen mode

authMethods.js

现在,如果你再创建一个帐户并进入浏览器开发工具

替代文本

替代文本

替代文本

_ 2. 签到 _

我们将复制并粘贴大量用于注册的内容,并轻松配置登录。

我们将从组件树的底部开始,逐个文件地稍微修改 Signin 组件,直到它在 authMethods 中正常工作。

首先创建一个名为 Signin.js 的新文件

替代文本

将所有内容从 Signup.js 复制并粘贴到 Signin.js

突出显示所有显示“注册”的地方,并将其更改为“登录”

如果您使用的是 Mac,请点击 React 组件的名称,然后按 Command + d。否则,您可以使用 ctrl + f 并在顶部输入。

我只有 3 个字,记得使用相同的方法将 handleSignup 更改为 handleSignin。

也改变按钮。

现在转到 App.js 并导入文件。

import Signin from './component/Signin'
Enter fullscreen mode Exit fullscreen mode

确保导入的组件文件夹是单数。

为登录添加新路线

<Route exact path='/' component={Signup} />
        <Route exact path='/signin' component={Signin} />

Enter fullscreen mode Exit fullscreen mode

如果您输入http://localhost:3000/signin,您的登录组件现在将会呈现,但是一旦您单击按钮,它就会崩溃,因为没有 handleSignin 函数。

为了解决这个问题,我们可以转到 AuthProvider.js 并复制并粘贴更改措辞,就像我们对注册所做的那样。然后将 handleSignin 函数添加到值对象。

const handleSignin = () => {
    //changed to handleSingin
    console.log('handleSignin!!!!')
    // made signup signin
    authMethods.signin(inputs.email, inputs.password, setErrors, setToken)
    console.log(errors, token)
  }

Enter fullscreen mode Exit fullscreen mode

现在将该函数添加到 firebaseAuth.Provider

 <firebaseAuth.Provider
    value={{
      //replaced test with handleSignup
      handleSignup,
      handleSignin,
      inputs,
      setInputs,
      errors,
    }}>
      {props.children}
    </firebaseAuth.Provider>
Enter fullscreen mode Exit fullscreen mode

AuthProvider.js

现在转到 authMethods.js 并执行类似操作,而不是 createUserWithEmailAndPassword,更改为... signInWithEmailAndPassword()

signin: (email, password, setErrors, setToken) => {
    //change from create users to...
    firebase.auth().signInWithEmailAndPassword(email,password) 
      //everything is almost exactly the same as the function above
      .then( async res => {
        const token = await Object.entries(res.user)[5][1].b
          //set token to localStorage 
          await localStorage.setItem('token', token)
          setToken(window.localStorage.token)
            console.log(res)
      })
      .catch(err => {
        setErrors(prev => ([...prev, err.message]))
      })
    },

Enter fullscreen mode Exit fullscreen mode

替代文本

如果您没有从本地存储中删除令牌,那么令牌仍然会存在。

替代文本

快到了!!

  1. 制作一个主页组件并只允许拥有令牌的用户到达那里。

  2. 制作一个注销按钮,删除令牌并使用 react-router-dom 将用户推出页面。

因为您应该已经在 authMethods.js 中了,所以这次我们将从顶部开始,然后转到底部。

与其他两种方法相比,这种方法非常简单,因为我们不使用 firebase 来保存用户的状态。

//no need for email and password
signout: (setErrors, setToken) => {
      // signOut is a no argument function
    firebase.auth().signOut().then( res => {
      //remove the token
      localStorage.removeItem('token')
        //set the token back to original state
        setToken(null)
    })
    .catch(err => {
      //there shouldn't every be an error from firebase but just in case
      setErrors(prev => ([...prev, err.message]))
      //whether firebase does the trick or not i want my user to do there thing.
        localStorage.removeItem('token')
          setToken(null)
            console.error(err.message)
    })
    },
  }
Enter fullscreen mode Exit fullscreen mode

转到 AuthProvider.js 并创建一个注销函数

const handleSignout = () => {
    authMethods.signout()
  }

Enter fullscreen mode Exit fullscreen mode

将方法添加到提供程序

setInputs,
errors,
handleSignout,
Enter fullscreen mode Exit fullscreen mode

现在我们需要一个组件来让它变得有用,但我们还没有这样做。

创建一个 Home.js,并在其中创建一个基本的 React 组件。

替代文本

替代文本

import React from 'react';

const Home = (props) => {
  return (
    <div>
      Home
    </div>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

导入 useContext 和 firebaseAuth

import React, {useContext} from 'react';
import {firebaseAuth} from '../provider/AuthProvider'
Enter fullscreen mode Exit fullscreen mode

在组件内部的 return 和 Home 之间,从 useContext 中解构 signout

  const {signout,} = useContext(firebaseAuth)
Enter fullscreen mode Exit fullscreen mode

在返回语句中。添加登录成功,然后添加一个在退出时调用的按钮。

 return (
    <div>
      Home, login successful!!!!!!
      <button onClick={signout}>sign out </button>
    </div>
  );
Enter fullscreen mode Exit fullscreen mode

在我们测试它之前,我们需要回到我们的组件树并改变访问每个组件的严格程度。

在 App.js 中,我们将使用三元语句来实现这一点,即如果没有将令牌保存到状态,用户就无法进入主页组件。

在 App.js 中导入 Home 组件。


import Home from './component/Home'
Enter fullscreen mode Exit fullscreen mode

使用 useContext 从 firebaseAuth 中解构令牌

  const { token } = useContext(firebaseAuth)
  console.log(token)
Enter fullscreen mode Exit fullscreen mode

当您使用 Route 渲染 Home 组件时,添加一个三元语句来检查令牌的数据类型

这意味着以不同的方式设置“/”或根 URL。

将您的 Home 组件路由更改为使用 render prop 而不是 component prop。并更严格地指定 URL 路径。

        <Route exact path='/' render={rProps => token === null ? <Signin /> : <Home />} />
        <Route exact path='/signin' component={Signin} />
        <Route exact path='/signup' component={Signup} />
Enter fullscreen mode Exit fullscreen mode

在 AuthProvider.js 中,将令牌添加到值对象。

<firebaseAuth.Provider
    value={{
      //replaced test with handleSignup
      handleSignup,
      handleSignin,
      token,
      inputs,
      setInputs,
      errors,
      handleSignout,
    }}>
      {props.children}
    </firebaseAuth.Provider>
Enter fullscreen mode Exit fullscreen mode

现在用户可以登录和退出了。最后一步,让用户注册时,react-router-dom 能够直接跳转到主页。

转到 Signup.js 并从 react-router-dom 导入 withRouter

import {withRouter} from 'react-router-dom'
Enter fullscreen mode Exit fullscreen mode

将默认导出传递给 withRouter 高阶组件


export default withRouter(Signup);
Enter fullscreen mode Exit fullscreen mode

向注册组件添加道具

const Signup = (props) => {
Enter fullscreen mode Exit fullscreen mode

现在我们可以访问 prop.history.push("/goAnyWhereInApp")

现在使 handleSubmit 成为一个异步函数并等待 handleSignup 然后推送到根 URL。

const handleSubmit = async (e) => {
    e.preventDefault()
    console.log('handleSubmit')
    //wait to signup 
    await handleSignup()
    //push home
    props.history.push('/')
  }
Enter fullscreen mode Exit fullscreen mode

您可能会有延迟,但一旦您获得凭证,它就会起作用。

如果你想发布这个视频,这里是如何使用 Surge 的。我是 Firebase 的忠实粉丝,我之所以做这些教程,是因为有一位开发者在 Heroku 上吃了不少苦头。

这是成品

这是github,如果可以的话请给它一颗星。

最后就是这样

您现在拥有一个具有强大后端功能的静态站点。

我将会做更多关于 firebase 的教程。

如果您发现本教程有用,请点赞并分享。

firebase文档很有帮助,但我这里有一些内容可以使其更容易地转换到 react 项目。

如果您有任何想说的,请在下面的评论中添加。

文章来源:https://dev.to/itnext/user-auth-with-firebase-and-react-1725
PREV
使用 JavaScript 获取当前设备类型
NEXT
React.js 令人惊叹的渲染属性模式 — — 生命周期消失了!