簡體   English   中英

使用 Firebase Auth 模擬器以編程方式創建用戶

[英]Create a user programatically using Firebase Auth emulator

我正在嘗試使用 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

測試非常簡單:

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 })
  })
})

並作為參考,索引文件:

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 }
}

我嘗試使用實際模擬器使用的 REST 端點(如下),它以相同的方式出錯。

http://localhost:9099/identitytoolkit.googleapis.com/v1/projects/<my-project>/accounts

無論如何,在使用 jest 時有沒有讓它運行? 或者我是否需要使用模擬器 UI 創建帳戶、導出它們並在運行測試時重新導入?

我發現我可以使用下面的 REST 端點在測試中創建一個用戶,但是它繞過了模擬器並成為一個真正的用戶。

https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=<api-key>

更新 jsdom 版本16.5.2

這個新版本現在支持 access-control-allow-headers 的通配符,因此更新到這個版本或使用它作為解決方案,對於使用 Create React App 創建的項目,可以解決這個問題。

jsdom 16.5.2 之前版本的解決方案

該錯誤由 jsdom 引發,因為它不支持 access-control-allow-headers 的通配符,但 firebase 使用通配符(請參閱 jsdom 的此問題與 firebase 相關的此拉取請求)。 有兩個開放的拉取請求來解決這個問題: https://github.com/jsdom/jsdom/pull/3073https://github.com/jsdom/jsdom/pull/2867

該問題可以通過手動更改node_modules文件夾中的相關代碼或使用 fork 作為package.json中的依賴項來解決:

"jsdom": "silviot/jsdom#fix/allow-headers"

如果jsdom不是直接依賴項,那么您可以在頂層的package.json中添加以下內容:

"resolutions": {
  "jsdom": "silviot/jsdom#fix/allow-headers"
}

如果使用了 fork,則jsdom文件夾中缺少一些自動生成的文件。 這些可以通過在文件夾中運行npm installyarn install來生成。 要自動執行此操作,您可以將prepare腳本添加到package.json

"scripts": {
  "prepare": "cd node_modules/jsdom && yarn"
},

我在 firebase 身份驗證模擬器中以編程方式創建用戶時也遇到了問題。

而不是使用

https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API_KEY]

您必須使用以下格式:

http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API_KEY]

然后給一個像這樣的 JSON 身體,然后點擊帖子

{
"email": "test@test.com",
"password": "test12"
}

瞧。 您的模擬器中有一個用戶。 將此與 fetch 或 axios 結合使用,如果您需要添加自定義聲明或其他信息,您可以為您的模擬器播種用戶。 在觸發用戶創建的函數模擬器中創建 function。

functions.auth.user().onCreate

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM