[英]Create a user programatically using Firebase Auth emulator
I am trying to write jest tests using the Firebase Auth emulator and continue to receive the following CORS error.我正在尝试使用 Firebase Auth 模拟器编写笑话测试,并继续收到以下 CORS 错误。
console.error
Error: Headers X-Client-Version forbidden
at dispatchError (/Users/me/my-project/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:62:19)
at validCORSPreflightHeaders (/Users/me/my-project/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:99:5)
at Request.<anonymous> (/Users/me/my-project/node_modules/jsdom/lib/jsdom/living/xhr/xhr-utils.js:367:12)
at Request.emit (events.js:315:20)
at Request.onRequestResponse (/Users/me/my-project/node_modules/request/request.js:1059:10)
at ClientRequest.emit (events.js:315:20)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:641:27)
at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)
at Socket.socketOnData (_http_client.js:509:22)
at Socket.emit (events.js:315:20) undefined
The test is very simple:测试非常简单:
import { renderHook, act } from "@testing-library/react-hooks"
import faker from "faker"
import { useAuth, FirebaseProvider, firebase } from "./index"
const wrapper = ({ firebase, children }) => {
return <FirebaseProvider firebase={firebase}>{children}</FirebaseProvider>
}
const createUser = ({ email = faker.internet.email(), password = faker.internet.password({ length: 6 }) } = {}) => {
return firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then(user => user)
}
const signUserIn = ({ email, password } = {}) => {
return firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then(user => user)
}
describe("useAuth", () => {
it("will return the user", async () => {
const { result } = renderHook(() => useAuth(), { wrapper, initialProps: { firebase } })
const email = faker.internet.email()
const password = faker.internet.password()
await act(async () => {
const user = await createUser({ email, password }) // this fails
await signUserIn({ email, password }) //and so does this
})
expect(result.user).toEqual({ email, password })
})
})
And for reference, the index file:并作为参考,索引文件:
const FirebaseProvider = ({ children, firebase }) => {
const firestore = firebase.firestore()
const auth = firebase.auth()
if (useEmulator()) {
firestore.useEmulator("localhost", 8080)
auth.useEmulator("http://localhost:9099/")
}
const value = { firestore, auth }
return <FirebaseContext.Provider value={value}>{children}</FirebaseContext.Provider>
}
const throwError = hook => {
throw new Error(`${hook} must be used within a FirebaseProvider`)
}
const useAuth = () => {
const context = useContext(FirebaseContext)
if (context === undefined) throwError("useAuth")
const [user, setUser] = useState()
useEffect(() => {
const cleanup = context.auth.onAuthStateChanged(authUser => {
authUser ? setUser(authUser) : setUser(null)
})
return () => cleanup()
})
return { ...context.auth, user }
}
I have tried using the REST endpoint that the actual emulator uses (below) and it errors in the same way.我尝试使用实际模拟器使用的 REST 端点(如下),它以相同的方式出错。
http://localhost:9099/identitytoolkit.googleapis.com/v1/projects/<my-project>/accounts
Is there anyway to get this to run when using jest?无论如何,在使用 jest 时有没有让它运行? Or do I need to create the accounts using the emulator UI, export them and re-import when I am running tests?
或者我是否需要使用模拟器 UI 创建帐户、导出它们并在运行测试时重新导入?
I have found I can use the REST endpoint below to make a user in the test, however it bypasses the emulator and makes a real user.我发现我可以使用下面的 REST 端点在测试中创建一个用户,但是它绕过了模拟器并成为一个真正的用户。
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=<api-key>
Update jsdom version 16.5.2更新 jsdom 版本16.5.2
This new version now supports wildcards for access-control-allow-headers, so updating to this version or using it as resolution, for projects created with Create React App, solves the problem.这个新版本现在支持 access-control-allow-headers 的通配符,因此更新到这个版本或使用它作为解决方案,对于使用 Create React App 创建的项目,可以解决这个问题。
Solution for jsdom prior to version 16.5.2 jsdom 16.5.2 之前版本的解决方案
The error is thrown by jsdom because it doesn't support wildcard for access-control-allow-headers, but firebase uses the wildcard (see this issue for jsdom and this pull request related to firebase ).该错误由 jsdom 引发,因为它不支持 access-control-allow-headers 的通配符,但 firebase 使用通配符(请参阅 jsdom 的此问题和与 firebase 相关的此拉取请求)。 There are two open pull requests to fix this issue: https://github.com/jsdom/jsdom/pull/3073 and https://github.com/jsdom/jsdom/pull/2867 .
有两个开放的拉取请求来解决这个问题: https://github.com/jsdom/jsdom/pull/3073和https://github.com/jsdom/jsdom/pull/2867 。
The issue can be fixed by either changing the relevant code manually in the node_modules
folder or by using the fork as dependency in the package.json
:该问题可以通过手动更改
node_modules
文件夹中的相关代码或使用 fork 作为package.json
中的依赖项来解决:
"jsdom": "silviot/jsdom#fix/allow-headers"
If jsdom
isn't a direct dependency, then you can add the following to the package.json
at the top level:如果
jsdom
不是直接依赖项,那么您可以在顶层的package.json
中添加以下内容:
"resolutions": {
"jsdom": "silviot/jsdom#fix/allow-headers"
}
If the fork is used there are some auto-generated files missing in the jsdom
folder.如果使用了 fork,则
jsdom
文件夹中缺少一些自动生成的文件。 These can be generated by running npm install
or yarn install
in the folder.这些可以通过在文件夹中运行
npm install
或yarn install
来生成。 To automate this you can add a prepare
script to the package.json
:要自动执行此操作,您可以将
prepare
脚本添加到package.json
:
"scripts": {
"prepare": "cd node_modules/jsdom && yarn"
},
I also had problems making users programaticly in the firebase auth emulator.我在 firebase 身份验证模拟器中以编程方式创建用户时也遇到了问题。
Instead of using而不是使用
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API_KEY]
You have to use the following format:您必须使用以下格式:
http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API_KEY]
Then giving a JSON body like this, and hit post然后给一个像这样的 JSON 身体,然后点击帖子
{
"email": "test@test.com",
"password": "test12"
}
And voila.瞧。 You have a user in your emulator.
您的模拟器中有一个用户。 Combine this with fetch or axios and you seed your emulator with users, If you need to add custom claims or other info.
将此与 fetch 或 axios 结合使用,如果您需要添加自定义声明或其他信息,您可以为您的模拟器播种用户。 create function in the functions emulator that triggers on user creation.
在触发用户创建的函数模拟器中创建 function。
functions.auth.user().onCreate
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.