๋ ๋น ๋ฅธ ๋ก์ปฌ ๊ฐ๋ฐ ๋ฐ ์ข ๋จ ๊ฐ ํ ์คํธ๋ฅผ ์ํด ์ธ์ฆ API๋ฅผ ์๋ฎฌ๋ ์ดํธํ ์ ์์ต๋๊น? Firestore ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ํ ํ๊ฒฝ(dev, testing, staging, prod)์ ๋ํด ์๋ก ๋ค๋ฅธ ํ๋ก์ ํธ๋ฅผ ์์ฑํ ํ์๊ฐ ์์ต๋๋ค. ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ๊ฐ๋ฐ์ ์ํด ๊ฐ์ ๋ชจ๋์ JSON ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์๋ํ๊ฑฐ๋ ๋ชจ๋ ํ๋ก์ ํธ์ ๋ํด ์๋ํ ์ ์์ต๋๋ค. ํ ์คํธ ์ผ์ด์ค ๋ฑ. ์ฌ์ฉ์ ๋ก๊ทธ์ธ, ์ญํ ๊ธฐ๋ฐ ํ์ ๋ฐ ์ผ๋ถ ์์ ์ด ์๋ ์ข ๋จ ๊ฐ ํ ์คํธ๋ฅผ ์์ฑํ ์ ์์ผ๋ ค๋ฉด ํ ์คํธ ์ฌ์ฉ์๋ฅผ ๊ฒฉ๋ฆฌํ๊ณ ๊ฑฐ๊ธฐ์์ ์ฌ์ฉ์๋ฅผ ์๋ ๋ฐ ์ง์ฐ๊ธฐ ์ํ ๋ณ๋์ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ๋ชจ๋ ํ ์คํธ ์ผ์ด์ค์ ๋ํด.
@vladimirdjurdjevic ์ฌ๋ ค ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค! ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ํ ์ผ ๋ชฉ๋ก์ ์์ง๋ง ์๋ฎฌ๋ ์ด์ ํ ์ธ์ฆ ์๋น์ค์ ์๊ณผ ์ด๋ฅผ ์ํํ๊ธฐ ์ํ ์ต์ ์ ์ ๋ต์ ์์ง ๊ฒฐ์ ํ์ง ์์์ต๋๋ค. ํน์ ํญ๋ชฉ(์: ์ต๋ช ์ธ์ฆ)์ ์๋ฎฌ๋ ์ดํธํ๊ธฐ๊ฐ ๋งค์ฐ ์ฌ์ด ๋ฐ๋ฉด ๋ค๋ฅธ ํญ๋ชฉ(์: SMS ์ธ์ฆ)์ ๋งค์ฐ ์ด๋ ต์ต๋๋ค.
๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๋น์ ์ด ์ธ๊ธํ ์๋ ํฌ ์๋ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํ์ฑํํ๊ณ ์ถ์ต๋๋ค!
์ง๋ฌธ: ์๋ฎฌ๋ ์ดํฐ์ ํจ๊ป ์ฌ์ฉํ Firebase ์ฌ์ฉ์๋ฅผ ๋ก์ปฌ๋ก ์กฐ๋กฑํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค๋ฉด ์ ์ฉํ ๊น์? ๋ค์๊ณผ ๊ฐ์ ๊ฒ:
firebase.auth().setEmulatedUser({
uid: 'abc123',
// ...
});
@samtstern setEmulatedUser()
๋ฅผ ํธ์ถํ๋ฉด functions.auth.user().onCreate()
์๋ฎฌ๋ ์ดํธ๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฅ๋ ํธ๋ฆฌ๊ฑฐ๋ฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ๋งค์ฐ ์ ์ฉํ ๊ฒ์
๋๋ค.
@samtstern ์ผ๋ถ ํ ์คํธ ์๋๋ฆฌ์ค์๋ ํ์คํ ๋์์ด ๋์ง๋ง ์ฌ์ ํ ๊ฐ๋ฐ์ ์ํ ์ค์ ์ธ์คํด์ค๊ฐ ํ์ํฉ๋๋ค. ๋ด ์๊ฐ์ ์๋ก ๋ค๋ฅธ ํ๊ฒฝ์ ๋ํด ์ฌ๋ฌ Firebase ํ๋ก์ ํธ๋ฅผ ๋ง๋๋ ๊ฒ์ ํผํ๊ณ ๋ก์ปฌ์์(์คํ๋ผ์ธ์ผ๋ก) ๊ฐ๋ฐํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค. ๋ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ์๋น์ค์ ๋ํ ๋ค์ํ ํ๊ฒฝ์ ์ง์ํ๋ ๊ฒ์ ๋๋ค. ๋์ผํ ํ๋ก์ ํธ์์ firestore ๋ฐ auth๋ฅผ ์ํด ๋ค๋ฅธ ํ๊ฒฝ์ ๋ง๋ค ์ ์๋ค๋ฉด ๋ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ํ๊ฒฝ๋ณ๋ก ํ๋ก์ ํธ๋ฅผ ๋ง๋ค ์ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ๊ทธ๊ฒ์ ์ ๋ง ๊ณจ์น ์ํ ์ผ์ ๋๋ค. ๋ชจ๋ ํ๊ฒฝ ๊ตฌ์ฑ, ๋ฐ์ดํฐ ๋ณต์ ๋ฑ. ์ด์์ ์ผ๋ก๋ ํ๋์ Firebase ํ๋ก์ ํธ๋ฅผ ๋ง๋ค ์ ์๊ณ ์๋ ํ ์คํธ๋ฅผ ์ํ ๋๋ฏธ ๋ฐ์ดํฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ Firestore์ฉ ์คํ ์ด์ง ํ๊ฒฝ์ ๋ง๋ค๊ณ ๊ฑฐ๊ธฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ก๋ํ๋ฉด ๋ฉ๋๋ค.
@noelmansour ์ข์ ์ง๋ฌธ์
๋๋ค! ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ ์ด๋ ต์ง ์์ต๋๋ค. signInAsEmulatedUser
๋ฐ signUpAsEmulatedUser
์ ๊ฐ์ ๋ ๊ฐ์ง ๋ค๋ฅธ ํธ์ถ์ด ํ์ํ ๊ฒ์
๋๋ค. ์ฌ๊ธฐ์ ๋ ๋ฒ์งธ ํธ์ถ๋ง ํจ์๋ฅผ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค.
@vladimirdjurdjevic ์ ๋ชจ๋ ๊ธฐ๋ฅ์ ๊ฐ์ถ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ต๊ณ ๋ผ๋ ๋ฐ ์ ์ ์ผ๋ก ๋์ํฉ๋๋ค. ์ฌ์ฉ์๋ฅผ ๋ก์ปฌ๋ก ์ค์ ํ ์ ์์ด ํด๊ฒฐ๋์ง ์๋ "๊ฐ๋ฐ์ ์ํ ์ค์ ์ธ์คํด์ค"์์ ํ์ํ ๊ฒ์ด ๋ฌด์์ธ์ง ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?
์ง๋ฌธ: ์๋ฎฌ๋ ์ดํฐ์ ํจ๊ป ์ฌ์ฉํ Firebase ์ฌ์ฉ์๋ฅผ ๋ก์ปฌ๋ก ์กฐ๋กฑํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค๋ฉด ์ ์ฉํ ๊น์?
์ ๋ง ์ ์ฉํฉ๋๋ค. ๋ง์ ๋์์ด ๋ ๊ฒ์
๋๋ค.
์ง๊ธ์ ๋ก์ปฌ์์ ๋ฌด์ธ๊ฐ๋ฅผ ํ
์คํธํด์ผ ํ ๋๋ง๋ค ๊ธฐ๋ก๋ ์ฌ์ฉ์๋ฅผ ๊ฒ์ฆํ๋ ๊ท์น ํจ์๋ฅผ true
์ค์ ํ๊ณ ์์ต๋๋ค. ์ด๊ฒ์ ๊ฝค ์์ ํ์ง ์์ง๋ง ์๋ฎฌ๋ ์ดํธ๋ ํ์ฌ ์ฌ์ฉ์ ์์ด ํ ์ ์๋ ๋ ๊ฐ๋จํ ์ผ์
๋๋ค.
์, ์ด๊ฒ์ ๋งค์ฐ ์ ์ฉํ ๊ฒ์ ๋๋ค.
๋ํ functions.auth.user().onCreate()
๋จ์ ํ
์คํธ๋ฅผ ํ๊ณ ์ถ์ต๋๋ค. ์ง๊ธ ๊ฐ์ฅ ์ข์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก onCreate
์ ๋ฌ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ด๋ณด๋ด๊ณ ๊ฐ์ง user
๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ ๊ฒ์
๋๋ค.
๊ทธ๋ฐ ์ข
๋ฅ์ ๋จ์ ํ
์คํธ๋ฅผ ์ํด firebase-functions-test๋ฅผ ํ์ธํ์ญ์์ค.
๋ชจ์ ๋ฐ์ดํฐ๋ก ํจ์ ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ๋ ๋ฐ ๋์์ด ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค.
2019๋ 10์ 13์ผ ์ผ์์ผ ์ค์ 5์ 44๋ถ Daniel K. [email protected]์ด ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค.
๋ํ functions.auth.user().onCreate() ๋จ์ ํ ์คํธ๋ฅผ ํ๊ณ ์ถ์ต๋๋ค. NS
์ง๊ธ ๊ฐ์ฅ ์ข์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ๋ฐฑ ๋ด๋ณด๋ด๊ธฐ๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค.
onCreate์ ์ ๋ฌ๋ ํจ์์ ๊ฐ์ง ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/firebase/firebase-tools/issues/1677?email_source=notifications&email_token=ACATB2QYJLX2LNVDTWJV25TQOMJ4VA5CNFSM4I27PTFKYY3PNVWWK3TUL52HS4DFWEXG43
๋๋ ๊ตฌ๋ ์ทจ์
https://github.com/notifications/unsubscribe-auth/ACTB2SO3IR6UB73F4EMZPTQOMJ4VANCNFSM4I27PTFA
.
@samtstern ์ค์ ๋ก Firestore ์๋ฎฌ๋ ์ดํฐ์ ํจ๊ป ์๋ํฉ๋๊น? ์ด๋ฅผ ๋ฐํ์ผ๋ก ๋ค๋ฅธ ๋ชฉ์ ์ ์ํ ๊ฒ์ด๋ผ๋ ์ธ์์ ๋ฐ์์ต๋๋ค.
https://firebase.google.com/docs/functions/unit-testing#initializing
๋๋ ํ์คํ ๋จ์ ํ ์คํธ๋ฅผ ์ํ ์จ๋ผ์ธ ๋ชจ๋๋ฅผ ์ํ์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ "stubbing"์ ํตํด Firestore ์๋ฎฌ๋ ์ดํฐ์ ์ก์ธ์คํ ์ ์๋์ง ํ์คํ์ง ์์ต๋๋ค.
@FredyC ํด๋น ๋ฌธ์๋ฅผ ์ง์ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. "๋ชจ๋"๊ฐ ํ์ฑํํ ์ ์๋ ์ค์์น๊ฐ ์๋๋ผ ์ทจํ ์ ์๋ ์ ๋ต์ ์ค๋ช ํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ๋ ๋จ์ด๊ฐ ํผ๋์ค๋ฝ์ต๋๋ค.
๋จ์ ํ
์คํธ์ ํจ๊ป Firestore ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์์ํ๋ ๊ฒฝ์ฐ ์ฝ๋๊ฐ ํ์คํ ์ฐ๊ฒฐ๋ ์ ์์ต๋๋ค. FIRESTORE_EMULATOR_HOST
ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๋ฉด Firebase Admin SDK๊ฐ ์๋์ผ๋ก Firestore ์๋ฎฌ๋ ์ดํฐ์ ์ฐ๊ฒฐ๋ฉ๋๋ค( firebase emulators:exec
๊ฐ ์๋์ผ๋ก ์ํ).
@samtstern ์ฌ์ ํ ์ ์ ์ฐ๊ฒฐํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ผ๋ฉฐ ์ด ๋ชจ๋ ๊ฒ์ด functions.auth.user().onCreate()
ํ
์คํธ์ ์ด๋ป๊ฒ ๋์์ด ๋ ๊น์? ๊ธฐ๋ฅ์ด ํ๋ก๋์
๋ฒ์ ์ด ์๋ ์๋ฎฌ๋ ์ดํฐ์ ์ฐ๊ฒฐ๋๋ ๊ฒ์ ์ข์๋ฐ Firestore๋ง ํด๋น๋๋ ๊ฒ์ด๊ฒ ์ฃ ? ํ
์คํธ์์ ์ฌ์ฉ์ ์์ฑ์ ํธ์ถํ์ฌ ์ค์ ๋ก ๊ธฐ๋ฅ ์ฝ๋๋ฅผ ์์ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
์ธ๊ธ๋ firebase-functions-test์ makeUserRecord
๋น๋ฐ์ค๋ฌ์ด ๋ฐฉ๋ฒ ์ด ์๋ ๊ฒ ๊ฐ์ง๋ง ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ๋๋ ์ค์ ๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๊ทธ๋ค์ง ์๋ฏธ๊ฐ ์์ต๋๋ค.
@firebase/testing
ํจํค์ง์์ auth.createUserWithEmailAndPassword()
๋ฅผ ํธ์ถํ๋ ค๊ณ ์๋ํ์ง๋ง ์ ํจํ์ง ์์ API ํค์ ๋ํด ๋ถํํ๋ฏ๋ก ์จ๋ผ์ธ ๋ฒ์ ์์๋ง ์๋ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์ธ๊ธํ env ๋ณ์์ ๋ํด org ๋ฅผ
๋๋ ๋ํ https://github.com/firebase/functions-samples๋ฅผ ํ์ํ์ง๋ง ๊ฑฐ๊ธฐ์์ ๋จ์ ํ ์คํธ์ ์๋ฅผ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
์ข ์ดํดํด ์ฃผ์๊ฒ ์ต๋๊น? :)
ํด๋ผ์ฐ๋ ํจ์ ์ฝ๋๊ฐ admin.auth().getUserByEmail()
ํธ์ถ์ ์ฌ์ฉํ๋ ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ๋๋๊ฒ๋ ์ค๋ฅ๋ก ๋๋์ง ์์ง๋ง ๋ฐํ๋ ์ ์๋๋ก ํด๋น ์ฌ์ฉ์๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ฌผ๋ก ์ ์ฒด ๊ด๋ฆฌ ๋ชจ๋์ ์กฐ๋กฑํ๋ ๊ฒ์ ์ ์ธํ๊ณ ๋ ๋ฏธ์น ์ง์
๋๋ค. :)
@samtstern ๋ฆ์ด์ ์ฃ์กํฉ๋๋ค. ๋ด๊ฐ ์ค์ ์ธ์คํด์ค๋ผ๊ณ ๋งํ ๋ ์ค์ ์ธ์คํด์ค๋ฅผ ์๋ฏธํฉ๋๋ค. D ์ด์์ ์ผ๋ก๋ ๊ฐ๋ฐ์ ์ํด ๊ฐ๋ ํ๊ฒฝ ํ์ผ์ ๊ตฌ์ฑ์ ๋ฐ๊พธ๊ณ ์ฑ์ด ์ค์ API์ ํต์ ํ๋ ๊ฒ๊ณผ ๊ฐ์ ์ธ์ฆ ๊ธฐ๋ฅ์ ๊ณ์ ๊ตฌํํ๊ณ ์ถ์ง๋ง ์ค์ ๋ก๋ ๋ด ์ปดํจํฐ์์ ์คํ๋๋ ์๋ฎฌ๋ ์ดํฐ์ ๋๋ค. ์คํ๋ผ์ธ์ผ๋ก ํ ์ ์์ต๋๋ค. ์ด์ ์๋ฅผ ๋ค์ด SMS๋ฅผ ๋ณด๋ผ ๋์ ์ด๋ ค์์ ์ดํดํฉ๋๋ค. ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ค์ SMS๋ฅผ ๋ด ์ ํ๋ก ๋ณด๋ผ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ๋ ๊ฒ์ ์ด๋ฆฌ์์ ์ผ์ด์ง๋ง, ์ฝ์์ ์ธ์ํ ์๋ ์์ต๋๋ค(์ ์ก๋ SMS์ ๋ด์ฉ). ์๋ง๋ ์ด๊ฒ์ ๋ํ ๊ฐ์น๋ณด๋ค ๋ ๋ฒ๊ฑฐ๋กญ์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ๋ก์ ํธ๋น ์ฌ๋ฌ ํ๊ฒฝ์ ์ง์ํ๋ ๊ฒ๋ง์ผ๋ก๋ ํจ์ฌ ๋ ๋์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ก ๋ค๋ฅธ ํ๊ฒฝ์ ์ฌ๋ฌ ํ๋ก์ ํธ ๊ฐ์ ๊ตฌ์ฑ์ ๋ณต์ ํ๋ ๋ฐ ๋๋ฌด ๋ง์ ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค. ๋ํ ์ฌ๋ฌ Firestore ํ๋ก์ ํธ์ ๋ฐ์ดํฐ๋ฅผ ์๋ํ ์ ์๋๋ก ์คํฌ๋ฆฝํธ์ ๋ํ ์ฌ๋ฌ ์๋น์ค ๊ณ์ ์ ๊ด๋ฆฌํ๋ ๊ฒ๋ ํ๋ ์ผ์ ๋๋ค. ์ด๊ฒ์ด ๋ด๊ฐ ์ ์ฒด Firebase ํ๋ซํผ์ ์๋ฎฌ๋ ์ดํธํ๋ฉด ๋ชจ๋ ๋นํ๋ก๋์ ํ๊ฒฝ์ ์ฌ์ฉํ ์ ์๊ณ ์ค์ Firebase ํ๋ก์ ํธ ํ๋๋ง ๊ด๋ฆฌํ ์ ์๋ค๊ณ ๊ฐ๋ฅด์น ์ด์ ์ ๋๋ค. ๊ทธ๋ฌ๋ ํ๋ก์ ํธ๋น ์ฌ๋ฌ ํ๊ฒฝ์ ์ง์ํ๋ ๊ฒ์ด ์์ฉ ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ๋ ๋ ๋์ ์๋ฃจ์ ์ผ ์ ์์ต๋๋ค.
@FredyC ๋ชจ๋ ํผ๋๋ฐฑ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ์ด๊ฒ์ด ์ผ๋ง๋ ํผ๋์ค๋ฌ์ธ ์ ์๋์ง ๋ณด๋ ๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ์ ๋ง ๋์์ด ๋ฉ๋๋ค. ์ฌ๋๋ค์ด ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ํ ์คํธ์์ ํ๊ณ ์ถ์ ๊ฒ์ ๋ ๊ฐ์ง์ ๋๋ค.
setEmulatedUser
๊ฒ์ด ํด๊ฒฐ๋ ๊ฒ์
๋๋ค. ์๋ฎฌ๋ ์ดํฐ๊ฐ ์๋ฝํ์ง๋ง ์ ํ์ ์ํด ๊ฑฐ๋ถ๋๋ ๊ฐ์ง ์ธ์ฆ ํ ํฐ์ ๋ก์ปฌ๋ก ๊ฐ์ง ์ ์์ต๋๋ค. ๋ ๋ง์ ์์ , ๋ ๋ง์ ๊ฒฉ๋ฆฌ ๋ฑ.onCreate
ํจ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํธ๋ฆฌ๊ฑฐ๋๋๋ก ํด๋น ์๋ฎฌ๋ ์ดํฐ์ ํจ์ ์๋ฎฌ๋ ์ดํฐ ๊ฐ์ ํตํฉ.admin.auth()
๊ฐ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํจ์ ์๋ฎฌ๋ ์ดํฐ ๋ด๋ถ์์ ์๋ ์กฐ๋กฑํฉ๋๋ค.๋ถ๋ช ํ (2)๊ฐ ์ฌ๋ฐ๋ฅธ ์ด์ผ๊ธฐ๋ผ๊ณ ์๊ฐํ์ง๋ง ๊ตฌํ ๋ฐ ์ ์ง ๊ด๋ฆฌ๊ฐ ํจ์ฌ ๋ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ ์ผ๋ง๋ ๋ง์ ์ฌ๋๋ค์ด (1)์ ๋ง์กฑํ ์ง ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ์ต๋๋ค.
@samttern ์๊ฒ ์ต๋๋ค . ๋ด๊ฐ ํ๋ ธ๋ค๋ฉด ์ ์ ํ์ง๋ง (1)์ ์ด๋ฏธ ํด๊ฒฐ๋์ง ์์์ต๋๊น? ํ ์คํธ์์ ๋ค์์ ํธ์ถํ๋ฉด Firestore ์๋ฎฌ๋ ์ดํฐ๊ฐ ๋๋ฅผ ํด๋น ์ฌ์ฉ์๋ก ์ธ์ํ์ฌ ๋ณด์ ๊ท์น์ ๋ํด ํ ์คํธํ ์ ์์์ ์๋ฏธํฉ๋๋ค. ๋๋ ์ค์ ๋ก ๊ทธ๊ฒ์ ์์ง ์๋ํ์ง ์์์ง๋ง ์ง๊ธ๊น์ง๋ ์ ๋งํด ๋ณด์ ๋๋ค :)
const app = firebase.initializeTestApp({
projectId,
auth: {
uid: 'owner'
}
})
(2)๋ ํ์คํ ๋งค์ฐ ์ ์ฉํ๊ฒ ๋ค๋ฆฌ์ง๋ง ํ์คํ ๋ค๋ฃจ๊ธฐ์๋ ํจ์ฌ ๋ ๋ณต์กํฉ๋๋ค. ์ฌํ๊ฒ๋ ์ ์ฒด ์ ํ์ ๋ํ ๋์ ํต์ฐฐ๋ ฅ์ ๋๋ฌด ์ ํ์ ์ด์ด์ ์ฌ๊ธฐ์ ์ ์ฉํ ์์ด๋์ด๋ฅผ ์ค์ ๋ก ์ ๊ณตํ ์ ์์ต๋๋ค.
์ฐจ๊ณก์ฐจ๊ณก ์์์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ํ ๋ฒ์ ๋ชจ๋ ์๋๋ฆฌ์ค๋ฅผ ๋ค๋ฃจ๋ ค๊ณ ํ๋ ๋์ ์๋ ค์ง ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถํ๊ณ ์ด๋ ์ค์ ์ถ๊ฐํ์ธ์. ๋ด ์ ํ๋ ์๊ฒฌ์ผ๋ก๋ ๊ธฐ๋ฅ ํธ๋ฆฌ๊ฑฐ์ ํจ๊ป "์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค"๋ฅผ ์๋ฎฌ๋ ์ดํธํ๋ ๊ฒ์ด ๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค.
@FredyC ๋น์ ์ (1)์ด ํ
์คํธ ์ค์ํธ ๋ด์์ ์ฌ์ฉํ๊ธฐ ์ํด ํด๊ฒฐ๋์๋ค๋ ๊ฒ์ด ๋ง์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ ์ค์ ๋ก ๋ก์ปฌ ๊ฐ๋ฐ์ ์ํด Android/iOS/์น ์ฑ์ ์๋ฎฌ๋ ์ดํฐ์ ์ง์ ์ฐ๊ฒฐํ๋ ๊ฒ์
๋๋ค. ์ด ๊ฒฝ์ฐ @firebase/testing
์ฌ์ฉํ ์ ์์ต๋๋ค.
์ ๊ฒ ์ด์. ์์งํ @firebase/testing
๋ฅผ ๋ณ๋์ ์๋ฃจ์
๋์ ํฌ๋ก์ค ํ๋ซํผ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค๋ฉด ์ ๋ง ์ข์ ๊ฒ์
๋๋ค. ํต์ ์ ์๋ฎฌ๋ ์ดํฐ๋ก ๋ฆฌ๋๋ ์
ํ๋ ๊ฒ์ด ์ผ๋ง๋ ์ด๋ ค์ธ ์ ์์ต๋๊น? ๋ฐ๋ก FIRESTORE_EMULATOR_HOST
์๋๊ฐ์? ์๋ฎฌ๋ ์ดํฐ์ ๋ค๋ฅธ ์๋น์ค๋ ํฌํจ๋๋ค๋ฉด FIREBASE_EMULATOR_HOST
์ ๊ฐ์ ๊ฒ์ด ๋ ์ ์ ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
@vladimirdjurdjevic ๋ด ์๊ฐ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก signInWithPhone
๋ฉ์๋๋ฅผ ์กฐ๋กฑํ์ฌ ๋์์ ์ ์ดํ ์ ์๋๋ก ์ค์ ๋ก ์๋ํ์ง ์์๊น์? ๊ทธ๋ฌ๋ฉด ์ฝ์์์ ์๋ฎฌ๋ ์ดํฐ์ ์๋ฎฌ๋ ์ด์
๋ SMS ์ฝ๋๋ฅผ ๋ฐ๋ ๊ฒ์ ๋ํด ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค. :)
๋ฌผ๋ก Firestore์ฉ ์๋ฎฌ๋ ์ดํฐ์ ๋ํด ์ธ์ฆํ๊ณ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค. ์ด์ https://github.com/firebase/firebase-tools/issues/1677#issuecomment -542897671์์ ์ค๋ช ํ ๊ฒ๊ณผ ๊ฐ์ ๊ฒ์ ๋๋ค. ๋ณด์๋์ง ์์ ํ ํฐ์ ์์ฑํ๋ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. https://github.com/firebase/firebase-js-sdk/blob/master/packages/testing/src/api/index.ts#L64. ๊ทธ๊ฒ์ด ํจ๊ณผ๊ฐ ์๋์ง ํ์คํ์ง ์์ต๋๋ค.
๋ฌผ๋ก ์ 3์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์กฐ๋กฑํ๋ ๊ฒ์ด ํญ์ ์ฌ์ด ๊ฒ์ ์๋์ง๋ง ์ผ๋จ ์์๋ด๋ฉด ํ๋ฅญํ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๊ฒฐ๊ตญ, ์ผ๋ฐ์ ์ผ๋ก ๋ ์ฝ๊ฒ ๋ง๋ค๊ธฐ ์ํด ์ผ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ถ์ถ๋ ์ ์์ต๋๋ค.
๋ํ ์ด๋ฌํ signIn ๋ฉ์๋๋ ์ ์ ํ ํ ์คํธ์์๋ ์ฒ๋ฆฌํด์ผ ํ๋ ๋ง์ ์ค๋ฅ ์ฝ๋๋ฅผ ๋์ง ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์กฐ๋กฑ์ผ๋ก๋ ์ฝ๊ฒ ํ ์ ์์ต๋๋ค.
@samtstern setEmulatedUser
์ ๊ฐ์ ์ฃผ์ ๋ก firebase.auth()
๋ค์์คํ์ด์ค ์ปจํ
์คํธ๋ฅผ ํ์ฅํ๋ ๊ฒ์ ๊ธฐ์กด ์๋ฎฌ๋ ์ด์
์ ๋ต์ ๋ฐํจํด์ฒ๋ผ ๋ณด์
๋๋ค. ์ด ๊ถ์ฅ ์ฌํญ์ ํจํค์ง ์ธก๋ฉด์ ํ์ฅ ์ฉ์ด์ฑ์ ์ํฅ์ ๋ฐ์ ์ ์์ต๋๊น?
๋ค๋ฅธ ์๋ฎฌ๋ ์ดํฐ์ ํจ๊ป ๋ณ๋์ ์ธ์ฆ ์๋น์ค ๊ณ์ธต์ด HTTP๋ฅผ ํตํด ์์๋ ๊ฒ์ผ๋ก ์์ํ๊ณ ํด๋ผ์ด์ธํธ ์ธก ๊ตฌ์ฑ์ด ๊ธฐ์กด API ํ๋ฉด์ ๋ฆฌ๋๋ ์ ํ์ฌ ํ์ฉํ ์ ์์ต๋๋ค.
๋๋ ์คํ๋ ค ํธ์ฌ AuthN ์ผ์ด์ค๊ฐ ์ฌ์ฉ์ ์ด๋ฆ/๋น๋ฐ๋ฒํธ๋ฅผ ํตํด ๊ธฐ๋ณธ ์ฌ์ฉ์์ ๋ํด CRUD๋ฅผ ์ต์ํ์ผ๋ก ์ง์ํ๋ Admin ๋ฐ Client API๋ก ์ค๋ฅ๋ฅผ ๋ฐํํ๊ธฐ๋ฅผ ์ํฉ๋๋ค. ์ ์ฅ, Admin๊ณผ signInWithCustomToken
์์ Custom Token ์ง์์ผ๋ก ์์ํ๋ ๊ฒ์กฐ์ฐจ ์ ๋ง ๋ฉ๋ฆฌ ๊ฐ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ฌธ์์ ๊ฒ์๋ API ์ง์ ๋งคํธ๋ฆญ์ค๋ก ๋ฎ์ ๋งค๋ฌ๋ฆฐ ๊ณผ์ผ์ ๊ตฌํํ ์๋ ์์ต๋๋ค.
@FredyC ๋ ํตํฉ ์ธ์ฆ ํ
์คํธ๋ฅผ ์ํ ํ์ฌ ์ ๋ต์ ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋์์ ์กฐ๊ฑด๋ถ๋ก @firebase/testing
๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉ์ ์ ์ initializeTestApp
ํธ์ถ๋ก ๋ผ์ฐํ
ํ๋ ๊ฒ์
๋๋ค. ์ด ์์
์ ํ๋ก์ ํธ ํ์ ๋น๋ ์ ํจํค์ง ์ ์ธ๋ฅผ ๊ฐ์กฐํ๊ณ ๋ ํจํค์ง API( initializeTestApp
๋ฐ firestore.settings
/ functions.useFunctionsEmulator
)์ ์๋ฎฌ๋ ์ดํฐ ๋ฆฌ๋๋ ์
๊ตฌ์ฑ์ ํ์ฐํฉ๋๋ค.
ํ์ฑ์ ํดํน!
ํตํฉ ์ธ์ฆ ํ ์คํธ๋ฅผ ์ํ ํ์ฌ ์ ๋ต์ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋์์ ์กฐ๊ฑด๋ถ๋ก
@firebase/testing
๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉ์ ์ ์initializeTestApp
ํธ์ถ๋ก ๋ผ์ฐํ ํ๋ ๊ฒ์ ๋๋ค.
์, ํ
์คํธ ๋ด์์ ๊ทธ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์์ต๋๋ค. ํธ๋ฆญ์ ์ผ๋ฐ initializeApp
ํจ์๋ฅผ ๊ฐ์ ธ์ค๋ index.ts
์๋ค๋ ๊ฒ์
๋๋ค. ์๋ฎฌ๋ ์ดํฐ๊ฐ ์์๋ ๋ ํธ์ถ๋์ง๋ง ํ
์คํธ๊ฐ ์คํ๋ ๋๋ ๋ค๋ฅธ ํ๋ก์ธ์ค์ด๋ฉฐ ์๋ก ์ถฉ๋ํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ค์ ๋ก ์กฐ๊ฑด๋ถ ์์
์ ๋ถ๋ด์ด ์์ต๋๋ค.
๋ฌผ๋ก ์ด๊ฒ์ ์ธ์ฆ ํ
์คํธ์ ๋ค๋ฅผ ์ ์์ต๋๋ค. ํ
์คํธ ๋ฌ๋๊ฐ ์ฑ ์ฝ๋์ ํ๋ก์ธ์ค๋ฅผ ๊ณต์ ํ๋ ์น ์ฑ. ๊ทธ๋ฌ๋ ๋จ์ ํ
์คํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ผ๋ฐ์ ์ผ๋ก ์ ์ฒด ์ฑ์ ํ
์คํธ๋ก ๊ฐ์ ธ์ค์ง ์์ต๋๋ค. initializeApp
๋ ํ
์คํธ์ ๊ด๋ จ์ด ์๊ณ ์ ํ ๊ฐ์ ธ์ค์ง ์๋ ์ผ๋ถ ์ฝ๋์์ ์ํ๋ ์ ์์ต๋๋ค.
@FredyC ๋จ์ ํ ์คํธ์ ๋ํด ๋ฌธ์ํ๋ ์ฌ์ฉ๋ฒ์ ๋์ํ์ต๋๋ค. API๊ฐ ๋ถ๊ธฐ๋๊ณ ๋์ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ๋ฌธ์ํ๋ ๋งต์์ ๋ฒ์ด๋๋ ์ ์ฒด ์ฑ ์๋๋ฆฌ์ค์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์์ต๋๋ค.
Honestly, it would be kinda superb if @firebase/testing could be used cross-platform instead of having separate solutions
๋ํ ์ ์์ ํ์๋ฅผ ํ๊ณ ์ถ์์ต๋๋ค. ๋์งํธ ํ์ดํ์ด๋ธ
@FredyC ๋ชจ๋ ํผ๋๋ฐฑ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ์ด๊ฒ์ด ์ผ๋ง๋ ํผ๋์ค๋ฌ์ธ ์ ์๋์ง ๋ณด๋ ๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ์ ๋ง ๋์์ด ๋ฉ๋๋ค. ์ฌ๋๋ค์ด ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ํ ์คํธ์์ ํ๊ณ ์ถ์ ๊ฒ์ ๋ ๊ฐ์ง์ ๋๋ค.
- ์ค์ ์ฌ์ฉ์๋ฅผ ์์ฑํ์ง ์๊ณ ๋ก๊ทธ์ธํ์ฌ Firestore ๋๋ Realtime Database์ ๊ฐ์ ์๋น์ค๋ฅผ ์ฌ์ฉํ์ญ์์ค. ์ง๊ธ ๋น์ฅ์
setEmulatedUser
๊ฒ์ด ํด๊ฒฐ๋ ๊ฒ์ ๋๋ค. ์๋ฎฌ๋ ์ดํฐ๊ฐ ์๋ฝํ์ง๋ง ์ ํ์ ์ํด ๊ฑฐ๋ถ๋๋ ๊ฐ์ง ์ธ์ฆ ํ ํฐ์ ๋ก์ปฌ๋ก ๊ฐ์ง ์ ์์ต๋๋ค. ๋ ๋ง์ ์์ , ๋ ๋ง์ ๊ฒฉ๋ฆฌ ๋ฑ- ์ค์ ๋ก ์ง์ ์ธ์ฆ์ ํ ์คํธํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ช ๊ฐ์ง ์กฐ๊ฐ์ด ์์ต๋๋ค.
NS. ์ธ์ฆ SDK๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์๋๋ก ํ์ํ ๋ชจ๋ API ํธ์ถ์ ์๋ตํ๋ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ์ ๋๋ค.
NS..onCreate
ํจ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํธ๋ฆฌ๊ฑฐ๋๋๋ก ํด๋น ์๋ฎฌ๋ ์ดํฐ์ ํจ์ ์๋ฎฌ๋ ์ดํฐ ๊ฐ์ ํตํฉ.
์จ. ์ค๋๋ Firestore ๋ฐ RTDB์์์ ๊ฐ์ดadmin.auth()
๊ฐ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ํจ์ ์๋ฎฌ๋ ์ดํฐ ๋ด๋ถ์์ ์๋ ์กฐ๋กฑํฉ๋๋ค.๋ถ๋ช ํ (2)๊ฐ ์ฌ๋ฐ๋ฅธ ์ด์ผ๊ธฐ๋ผ๊ณ ์๊ฐํ์ง๋ง ๊ตฌํ ๋ฐ ์ ์ง ๊ด๋ฆฌ๊ฐ ํจ์ฌ ๋ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ ์ผ๋ง๋ ๋ง์ ์ฌ๋๋ค์ด (1)์ ๋ง์กฑํ ์ง ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ์ต๋๋ค.
@samtstern ์ฐ์ ์ด๋ฐ ์ข ๋ฅ์ ์๋ฎฌ๋ ์ด์ ์ โค๏ธํ๊ณ ์ถ์ต๋๋ค.
๋๋ ์๋์ค๋ฅผ ๋ณผ ๊ฒ์ ๋๋ค. 1 e2 ํ ์คํธ๋ฅผ ์์ฑํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ํ์ฌ ํธ์คํ , ๊ท์น, Firestore ๋ฐ ๊ธฐ๋ฅ์ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ ๋์ ์ธ์ฆ์ ์ํด ์ค์ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
firebase.initializeTestApp์์์ ๋์ผํ ๋ฐฉ์์ผ๋ก setEmulatedUser๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์๋ฅผ ์กฐ๋กฑํ๋ ๊ฒ์ด ๊ฐ๋ฅํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ์ฉ์ ์ ์ ํ ํฐ ๋ฐ ๊ธฐํ ์ฌ์ฉ์ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ์ ์ถํ ์ ์์ด์ผ ํฉ๋๋ค.
firebase.auth().signInWithCredential(credential)
๋ก ํด๋ผ์ด์ธํธ ์ฑ์์ ์ฌ์ฉํ ์ ์๋ ์ํ ์๊ฒฉ ์ฆ๋ช
์ ์ป์ ์๋ ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ์ ๊ธฐํด ์ฃผ์ @vladimirdjurdjevic ์๊ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ์ฐ๋ฆฌ๋ ์ด๋ฏธ ๊ฑฐ์ 1๋ ๋์ ์๋ฃจ์ ์ ์ฐพ๊ณ ์์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์ธ ๊ฐ์ง์ ๋ํ ์ค์ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๋ณด๊ณ ์ถ์ต๋๋ค.
๋น์ ์ด ๊ณง ์ฐ๋ฆฌ๋ฅผ ์ํด ๋ฌด์ธ๊ฐ๋ฅผ ์ถ์ํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๊ทธ๊ฒ์ ๋น์ ์ ์ ํ์ ๋ ๊ฐ์น ์๊ฒ ๋ง๋ค ๊ฒ์ ๋๋ค! ์ด๋ฌํ ์๋น์ค์์๋ ๊ฐ๋ฐ์ ์์ฐ์ฑ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค!
์ด๊ฒ์ ๋ง์ ์ฌ๋๋ค์ ์์๋ฆฌ์คํธ์ ์๋ ๊ธฐ๋ฅ์ธ ๊ฒ ๊ฐ์ต๋๋ค. Firebase ์ธ์ฆ์ ํ์ฌ ๊ฐ๊ฒฉ ์ธก๋ฉด์์ 1์ IDaaS์ธ ๊ฒ ๊ฐ์ผ๋ฏ๋ก Cloud Functions๋ฅผ ์ฌ์ฉํ์ฌ ๋ก์ปฌ์์ ๊ฐ๋ฐํ ์ ์๋ค๋ ๊ฒ์ ์ ๋ง ๊ณ ํต์ค๋ฌ์ด ์ผ์ ๋๋ค. FB ํ์ ๊ณง ์ ๋ฐ์ดํธ๊ฐ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค! ๐
ํธ์ง: ์ด ์ค๋ ๋๊ฐ ๋ฌธ์ ์ ๋ฌปํ ์๊ธฐ ๋๋ฌธ์ @ firebase -ops์์
๋๋ ๋ํ์ด ์ค๋ฅ๊ฐ ์์ต๋๋ค ... ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์กด์ฌํ์ง ์๊ฑฐ๋ ์คํ๋๊ณ ์์ง ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ฅ์ด ๋ฌด์๋์์ต๋๋ค.
์ด๊ฒ์ ๋ค์ ์ฝ๋์ ์ํด ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค.
function.auth.user().onDelete()
์ด๊ฒ์ ๋ํ ๋ชจ๋ ์ ๋ณด ...
@๋๋ฏธ๋ํฌํด๋
๋๋ ๋น์ ์ ์์ ์ ๋์ํฉ๋๋ค. ๊ทธ ๋์ ๋์์ด ๋ ์ ์๋ ํ ๊ฐ์ง ํ:
๋ฌผ๋ก ๋ชจ๋ ๊ฐ๋ฐ์๋ ์์ ์ Firebase ํ๋ก์ ํธ๋ฅผ ๋ง๋ค ์ ์์ง๋ง ์ฌ์ ํ Firebase ๋์๋ณด๋์์ ํ ์คํธ ์ฌ์ฉ์๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ฏ๋ก ์ด์์ ์ด์ง ์์ต๋๋ค.
Firebase ๊ด๋ฆฌ SDK(์: auth().createUser
)๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ์ฌ์ฉ์๋ฅผ ์๋ํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. https://firebase.google.com/docs/auth/admin/manage-users ๋
์ด ์ค๋ ๋๋ฅผ ์ฝ์ ํ ์ฌ๊ธฐ ์ฌ๋๋ค์ด Foundry๋ฅผ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ๋ Foundry์ ๊ณต๋ ์ค๋ฆฝ์ ์ค ํ ๋ช ์ ๋๋ค. Foundry๋ Firebase Cloud Functions๋ฅผ ๊ฐ์ ธ์์ ์ฝ๋๋ฅผ ์ง์ ์คํํ๋ ๊ฐ๋ฐ ํ๊ฒฝ ์ญํ ์ ํ๋ ๋น์ฌ ์๋ฒ์ ํ๋ก๋์ Firebase ์ฑ์ ์ฌ๋ณธ์ ์์ฑํ๋ CLI ๋๊ตฌ์ ๋๋ค. ๊ตฌ์ฑ์ด ํ์ํ์ง ์์ต๋๋ค.
Foundry๋ ์์ค ์ฝ๋ ํ์ผ์ ๊ฐ์ํ๊ณ ์ฝ๋๋ฅผ ๋ก์ปฌ์ ์ ์ฅํ ๋๋ง๋ค ์๋ฒ์์ ์คํํ๊ณ ๋จ ๋ช ์ด ์์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ด ๋งค์ฐ ๋น ๋ฆ
๋๋ค.
๊ฐ๋ฐ ์ค์ ์ฌ์ฉํ ์ ์๋๋ก YAML ํ์ผ์ ํตํด ํ๋ก๋์
์ฑ์์ ๋ณต์ฌํด์ผ ํ๋ Firestore, RealtimeDB ๋ฐ ์ธ์ฆ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํฉ๋๋ค.
users:
- getFromProd: 5 # Copy first 5 users from your Firebase project
- getFromProd: ['id-1', 'id-2'] # Copy users with the specified IDs from your Firebase project
# Copy first 3 documents from production from the collection 'userWorkspaces'
# also add a custom document with id 'new-user-workspace' with a new data
# format that you want to use
firestore:
- collection: userWorkspaces
docs:
- getFromProd: 3
- id: new-user-workspace
data: {"newDataFormat": 42}
๋ํ ์ฝ๋๋ฅผ ์คํํ ๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฅ์ ํธ๋ฆฌ๊ฑฐํ๋ ๋ฐฉ๋ฒ์ ์ง์ ํฉ๋๋ค. ํด๋ผ์ฐ๋ ๊ธฐ๋ฅ์ ๋ํ REPL๊ณผ ์ ์ฌํ๊ฒ ์๋ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด ํด๋ผ์ฐ๋ ๊ธฐ๋ฅ์ด ์ผ๋จ ๋ฐฐํฌ๋๋ฉด ํ๋ก๋์
๋ฐ์ดํฐ์ ํ๋ก๋์
ํ๊ฒฝ์์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ค๋ ๊ฒ์ ํญ์ ํ์ ํ ์ ์์ต๋๋ค.
๋ํ ํด๋ผ์ฐ๋ ๊ธฐ๋ฅ์ ๋ฐฐํฌ๋ ๊ฒ์ฒ๋ผ ์๋ํฉ๋๋ค.
์ด๋ฌํ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ธ์ ์ ์์ํ๋ฉด ์์๋ก ์์ฑ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํ์ ๋ชจ๋ ์ฌ๋์ ์์ ์ ํ๊ฒฝ์์ ์์ ํ ์ ์์ต๋๋ค.
๋๋ ์ฌ๊ธฐ์์ ํ ๋ก ์ ์คํธํ๊ณ ์ถ์ง ์์ผ๋ฏ๋ก ์ง๋ฌธ์ด ์์ผ์๋ฉด ์ธ์ ๋ ์ง
์ด๋ฉ์ผ์ ๋ณด๋ด์ฃผ์๋ฉด ํ๋ก์ ํธ์ Foundry๋ฅผ ์ค์ ํ๋ ๋ฐ ๋์์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ ๊ทํ๊ฐ ์ค๋ช
ํ ๋ฐฉ๋ฒ๊ณผ ํํ์ด์ง์์ ์ฝ์ ๋ด์ฉ์ ๋ฐ๋ฅด๋ฉด ํด๋น ์๋น์ค๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ์
๋๋ค.
Firebase ์๋ฎฌ๋ ์ดํฐ๋ ๋์ ์คํ๋ผ์ธ์์๋ ์๋ํ๋ฏ๋ก ์๋ ํ
์คํธ์ ์ ์ฉํฉ๋๋ค.
@samtstern ์ด ๋ฌธ์ /๊ธฐ๋ฅ์ ๋ํ ์งํ ์ํฉ์ด๋ ๋ค๋ฅธ ์๋ฃจ์ ์ด ์์ต๋๊น? ๋ก์ปฌ์์ ์๋ ํ ์คํธ๋ฅผ ์ํํ ์ ์๋๋ก ํด๋ผ์ฐ๋ Firestore ์๋ฎฌ๋ ์ดํฐ์ ํจ๊ป ์์ ํ๋ ค๋ฉด (1) setEmulatedUser๊ฐ ํ์ํฉ๋๋ค. ๋ ๋ค๋ฅธ ์ต์ ์ ์๋ฎฌ๋ ์ดํฐ๊ฐ ์์๋ ๋ ์ฌ์ฉ์ ID๋ฅผ ์ค์ ํ๋ ๋ช ๋ น์ค ์ธ์๋ฅผ ๊ฐ๋ ๊ฒ์ ๋๋ค. ์ด๋ฐ ์์ผ๋ก ์๋ฎฌ๋ ์ดํฐ๋ ์์ ์ค์ ์ ๋ฌ๋ ์ฌ์ฉ์ ID๋ก ์คํ๋ฉ๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๊ท์น์ ๋ก์ปฌ์์ ํ ์คํธํ ์ ์์ต๋๋ค.
๊ทํ์ ์๊ฒฌ์ ๋ฐ๋ผ: 2019๋
10์ 17์ผ
_๋๋ ๋ถ๋ช
ํ (2)๊ฐ ๋ง๋ ์ด์ผ๊ธฐ๋ผ๊ณ ์๊ฐํ์ง๋ง ๊ตฌํ ๋ฐ ์ ์ง ๊ด๋ฆฌ๊ฐ ํจ์ฌ ๋ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ ์ผ๋ง๋ ๋ง์ ์ฌ๋๋ค์ด (1)์ ๋ง์กฑํ ์ง ์ดํดํ๋ ค๊ณ ๋
ธ๋ ฅํ์ต๋๋ค.
(1) ์ค์ ์ฌ์ฉ์๋ฅผ ์์ฑํ์ง ์๊ณ Firestore ๋๋ Realtime Database์ ๊ฐ์ ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋ก๊ทธ์ธํฉ๋๋ค. ๋ฐ๋ก ์ง๊ธ ๊ทธ๊ฒ์ด setEmulatedUser์ ๊ฐ์ ๊ฒ์ด ํด๊ฒฐ๋ ๊ฒ์ ๋๋ค. ์๋ฎฌ๋ ์ดํฐ๊ฐ ์๋ฝํ์ง๋ง ์ ํ์ ์ํด ๊ฑฐ๋ถ๋๋ ๊ฐ์ง ์ธ์ฆ ํ ํฐ์ ๋ก์ปฌ๋ก ๊ฐ์ง ์ ์์ต๋๋ค. ๋ ๋ง์ ์์ , ๋ ๋ง์ ๊ฒฉ๋ฆฌ ๋ฑ_
์ฐ๋ฆฌ๋ ์์ ํ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ด์ฌํ ๋
ธ๋ ฅํ๊ณ ์์ต๋๋ค.
๋ชจ๋๊ฐ ์ํ๋. ์ง๊ธ ์ ๊ณตํ ์ ์๋ ์ผ์ ์ ์์ง๋ง ์ฐ์ ์์๊ฐ ๋์ต๋๋ค.
์ฐ๋ฆฌ๋ฅผ ์ํด.
2020๋ 5์ 22์ผ ๊ธ์์ผ ์ค์ 8์ 12๋ถ์ ChuckB [email protected]์์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ์ต๋๋ค.
@samtstern https://github.com/samtstern ์งํ ์ํฉ ๋๋ ๊ธฐํ
์ด ๋ฌธ์ /๊ธฐ๋ฅ์ ๋ํ ์๋ฃจ์ ์ ๋ฌด์์ ๋๊น? ์์ ํ๋ ค๋ฉด (1) setEmulatedUser๊ฐ ํ์ํฉ๋๋ค.
ํด๋ผ์ฐ๋ Firestore ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ก์ปฌ์์ ์๋ ํ ์คํธ๋ฅผ ์ํํ ์ ์์ต๋๋ค.๊ทํ์ ์๊ฒฌ์ ๋ฐ๋ผ: 2019๋ 10์ 17์ผ
_ ๋๋ ๋ถ๋ช ํ (2)๊ฐ ๋ง๋ ์ด์ผ๊ธฐ๋ผ๊ณ ์๊ฐํ์ง๋ง ๋๋
ํจ์ฌ ๋ ๊ฐ๋จํ๊ธฐ ๋๋ฌธ์ ์ผ๋ง๋ ๋ง์ ์ฌ๋๋ค์ด (1)์ ๋ง์กฑํ ๊ฒ์ธ๊ฐ?
๊ตฌํํ๊ณ ์ ์งํฉ๋๋ค.(1) ๋ก๊ทธ์ธ ์์ด Firestore ๋๋ Realtime Database์ ๊ฐ์ ์๋น์ค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด
์ค์ ๋ก ์ค์ ์ฌ์ฉ์๋ฅผ ์์ฑํฉ๋๋ค. ์ง๊ธ์ ๊ทธ๋ฐ ๊ฒ ๊ฐ๋ค.
setEmulatedUser๊ฐ ํด๊ฒฐํ ๊ฒ์ ๋๋ค. ๊ฐ์ง ์ธ์ฆ์ ํ์ฉํ ๋ฟ์ ๋๋ค.
์๋ฎฌ๋ ์ดํฐ๊ฐ ์๋ฝํ์ง๋ง ๊ฑฐ๋ถํ ๋ก์ปฌ ํ ํฐ
์ฐ๋ฅด๋ค. ๋ ๋ง์ ์์ , ๋ ๋ง์ ๊ฒฉ๋ฆฌ ๋ฑ_โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-632660684 ,
๋๋ ๊ตฌ๋ ์ทจ์
https://github.com/notifications/unsubscribe-auth/ACATB2Q4LV7NXMQFEALNPXLRSZT25ANCNFSM4I27PTFA
.
1. ์ค์ ์ฌ์ฉ์๋ฅผ ์์ฑํ์ง ์๊ณ ๋ก๊ทธ์ธํ์ฌ Firestore ๋๋ Realtime Database์ ๊ฐ์ ์๋น์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ฐ๋ก ์ง๊ธ ๊ทธ๊ฒ์ด setEmulatedUser์ ๊ฐ์ ๊ฒ์ด ํด๊ฒฐ๋ ๊ฒ์ ๋๋ค. ์๋ฎฌ๋ ์ดํฐ๊ฐ ์๋ฝํ์ง๋ง ์ ํ์ ์ํด ๊ฑฐ๋ถ๋๋ ๊ฐ์ง ์ธ์ฆ ํ ํฐ์ ๋ก์ปฌ๋ก ๊ฐ์ง ์ ์์ต๋๋ค. ๋ ๋ง์ ์์ , ๋ ๋ง์ ๊ฒฉ๋ฆฌ ๋ฑ
๋๋ ์ฌ๊ธฐ์ 1๋ฑ์ผ๋ก ๋ง์กฑํ ๊ฒ์ด๋ค. ๊ทธ ์ฌ์ด์
https://stackoverflow.com/questions/62736060/firebase-test-auth-cloud-functions-locally
์์ง๋ ๋ถ๊ฐ๋ฅํ๊ฐ์?
@rishishingh-dev ํ์ฌ Firebase ์๋ฎฌ๋ ์ดํฐ๊ฐ ์ ๊ณตํ์ง ์๊ธฐ ๋๋ฌธ์ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์คํํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฅ์ ํ ์คํธํ๋ ๊ฒ์ ์๋ฒฝํ๊ฒ ๊ฐ๋ฅํฉ๋๋ค. ์ผ๋ถ ์ธ์ฆ API๊ฐ ํ์ํ ํจ์๋ฅผ ๋ฆฌํฉํฐ๋งํ๊ณ ํ ์คํธ์์ ๋ชจ์ํ ์ ์์ผ๋ฉฐ Firebase ํจ์ ํ์ผ์ ์ค์ API๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ํ ์คํธ ์ค์ ์ ์ถฉ์ค๋๋ ๋ ๋ฎ์ง๋ง ์ข ๋ฅ์ ๋ฌธ์ ๊ฐ ์๋๋ผ ์ ๋์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค. ์ธ์ฆ ํธ์ถ์ ์ง์ ํ ์คํธํ๋ ๊ฒ์ด์ง๋ง ์์ํ ๋๋ก ํ ์คํธํ ์ ์์ต๋๋ค.
๊ทธ SO ์ง๋ฌธ์์๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ๋๋ค.
function sendWelcomeEmail(user) {
console.log(user.uid);
console.log(user.email);
console.log(user.displayName);
}
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => sendWelcomeEmail(user));
๊ทธ๋ฆฌ๊ณ ํ
์คํธ์์ sendWelcomeEmail
์ง์ ํธ์ถํ์ฌ ํ์ํ ์์
์ ์ํํ๋์ง ํ์ธํฉ๋๋ค.
addFriend
๋ผ๋ ๋ ๋ณต์กํ ํด๋ผ์ฐ๋ ํจ์๊ฐ ์๋ค๊ณ ์์ํด๋ณด์ญ์์ค. ์ฌ๊ธฐ์ ์ฌ์ฉ์๋ ์น๊ตฌ ์ด๋ฉ์ผ์ ์
๋ ฅํ๊ณ uid๋ฅผ ์ํฉ๋๋ค. getUserByEmail
์ ํตํด ์ป์ ์ ์์ต๋๋ค.
function addFriend(email, getUserByEmail ) {
const friendUid = getUserByEmail(email);
// do things with friendUid;
}
exports.addFriend = functions.https.onCall(async (data, context) => {
const email = data.email;
const getUserByEmail = (email) => admin.auth().getUserByEmail(email);
return { res: await addFriend(email, getUserByEmail ) };
}
ํด๋ผ์ฐ๋ fn ์ ์ธ์์ ์ค์ getUserByEmail
๋ฅผ ๋ณด๋ด์ง๋ง ํ
์คํธ์์๋ ๋์ ๊ฐ์ง๋ฅผ ๋ณด๋
๋๋ค.
async function testAddFriend() {
const emails = {"[email protected]": "test-uid")
const fakeGetUserByEmail = (email) => emails[email];
addFriend("[email protected]);
// verify the things were done with friendUid
}
์ด๊ฒ์ด ๋จ์ ํ ์คํธ์์ ํ์ฌ API๋ฅผ ํ ์คํธํ๋ ๊ฒ๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. Firebase ์๋ฎฌ๋ ์ดํฐ์์ ์ธ์ฆ์ ์ ๊ณตํ๋ฉด ์ข ๋จ ๊ฐ ํ ์คํธ ์๋๋ฆฌ์ค์ ๋ํ ์์ฉ๊ตฌ๊ฐ ์ ๊ฑฐ๋์ง๋ง ํ ์คํธ ๊ฐ์ ์๊ตฌ ์ํ๊ฐ ์ ์ง๋๋ ๊ฒ์ ์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋จ์ ํ ์คํธ๋ฅผ ํฌ๊ฒ ๋ณ๊ฒฝํ์ง ์์ต๋๋ค.
ํ์ธํ๊ธฐ ์ํด ํด๋ผ์ฐ๋์ ์ ๋ก๋ํ ํ์ ์์ด ๋ก์ปฌ์์ ์คํํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
export const onCreate = functions.auth.user().onCreate((user) => {
addGravatarURLtoUserData(user.uid, user.email)
})
export const addGravatarURLtoUserData = async (uid, email) => {
const hash = crypto.createHash("md5").update(email).digest("hex")
await admin.database().ref(`users/${uid}`).update({ gravatarURL: uid })
}
๊ทธ๊ฑด ๊ทธ๋ ๊ณ , onCreate ํจ์ ๋ด์์ user.displayName์ ์ป์ ์ ์์ต๋๊น?
๋ค ์ค์ ๋์ด ์๋ค๋ฉด ์๋ํด ๋ณด์ จ๋์?
์, null์ ๋ฐํํฉ๋๋ค.
ํด๋ผ์ฐ๋์์ ์๋ํ์ต๋๋ค(๋ก์ปฌ์ด ์๋).
๋ด ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ์์ต๋๋ค.
exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
console.log(user.uid);
console.log(user.email);
console.log(user.displayName);
});
ํฅ๋ฏธ๋กญ๊ฒ๋ ํ์ ์ด๋ฆ์ ์ฌ์ฉํ์ง ์๊ณ ์ฌ์ฉ์ ์ง์ ์ฌ์ฉ์ displayName์ ์ฌ์ฉํฉ๋๋ค.
์ค์๊ฐ DB
/**
* updates Custom data in the realtime datastore users object, except for the username
* <strong i="7">@param</strong> data
* <strong i="8">@returns</strong> {Promise<void>}
*/
export async function updatePersonalData(data) {
const { displayName } = data
try {
await firebase
.database()
.ref("users/" + firebase.auth().currentUser.uid)
.update({
displayName: displayName,
})
userDataStore.update((user) => {
return { ...user, displayName: displayName }
})
} catch (e) {
alert(e.message)
}
}
2020๋
7์ 10์ผ ๊ธ์์ผ 10:44 rishingh-dev [email protected]
์ผ๋ค:
์, null์ ๋ฐํํฉ๋๋ค.
ํด๋ผ์ฐ๋์์ ์๋ํ์ต๋๋ค(๋ก์ปฌ์ด ์๋).[์ด๋ฏธ์ง: ์คํฌ๋ฆฐ์ท 2020-07-10 at 2 43 AM 12 AM]
https://user-images.githubusercontent.com/56976320/87140958-29f3ac80-c257-11ea-98d3-084fad619de7.png๋ด ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ์์ต๋๋ค.
console.log(user.uid);
console.log(์ฌ์ฉ์.์ด๋ฉ์ผ);
console.log(user.displayName);
});```โ
์ด ์ค๋ ๋์ ๊ฐ์ ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ ์์ต๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-656587759 ,
๋๋ ๊ตฌ๋ ์ทจ์
https://github.com/notifications/unsubscribe-auth/AABU35Q27EMMHYAYU5CNZR3R23PIDANCNFSM4I27PTFA
.>
์๋ถ
๋์ฝ์ค ์นด์น์นด๋์ค
๋ค, ์ ์ฃผ์ ๋ชฉํ๋ onCreate
ํจ์ ๋ด๋ถ์ ์ฌ์ฉ์ ์ ๋ณด๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ฒ์ด์์ต๋๋ค.
ํ์ง๋ง displayName
์ป์ ์ ์๊ธฐ ๋๋ฌธ์ onCallable
ํจ์๋ฅผ ๋ง๋ค์ด ์คํํ์ต๋๋ค.
๊ฐ์ฌ ํด์.
@samtstern ์ด ์์ ์ ํ๋ ๊ฒ์ ๋ณด๊ฒ ๋์ด ๋งค์ฐ ๊ธฐ์ฉ๋๋ค :) ๋ฐฉ๊ธ
๋ ๋ค๋ฅธ ๊ฐ์ฅ ์ข์ ์ ์ ๋ณด์ ์์ด ํฌ๋กฌ์ ์ด ํ์๊ฐ ์๋ค๋ ๊ฒ์ ๋๋ค.
@samtstern
๋ ๋ฌ์ด ์ง๋ ์ง๊ธ, ๋๋ต์ ์ธ ๊ฒฌ์ ์ ๋ผ ์ ์์ต๋๊น?
๋ด๋ ์ด์ ์ถํํ๊ณ ์ถ์ต๋๋ค. ์ด์ ์ฐ๋ฆฌ๋ ์ค์ ํ๋ก์ ํธ์ ๋ํ ํตํฉ ํ ์คํธ๋ฅผ ์์ฑํ ๊ฒ์ธ์ง ์๋๋ฉด ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ํด ๋ช ๋ฌ์ ๊ธฐ๋ค๋ ค์ผ ํ ๊ฒ์ธ์ง ๊ฒฐ์ ํด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ฅผ ์กฐ๊ธ ๋์์ฃผ์๊ฒ ์ต๋๊น?
์ต์์,
๋ํด๋ผ์ค
Firebase์ ์ ์ฑ ์ 100% ํ์ ํ ์ ์๋ ๊ฒฝ์ฐ ์ถ์ ์์ ์ ๋ํ ์ถ์ ์น๋ฅผ ์ ๊ณตํ์ง ์๋ ๊ฒ์ ๋๋ค. ์ง๊ธ ์ฐ๋ฆฌ๋ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ์ ๋ํด ์ด์ฌํ ๋ ธ๋ ฅํ๊ณ ์์ง๋ง ์ถ์ ๋ ์ง๋ฅผ ์ ํํ๊ธฐ์๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค.
๊ทธ๊ฒ์ ์ฐ๋ฆฌ์ ์ต์ฐ์ ์์ ์ค ํ๋์ด์ง๋ง, ์ฐ๋ฆฌ๊ฐ ๋น์ ์ ์ฑ ํ ์คํธ๋ฅผ ์์ํ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ฉด ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ค๋ prod์ ๋ํ ํ ์คํธ๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๋์์ผ๋ก ํ๋๋ก ์ ํํ์ญ์์ค.
์๊ฒ ์ต๋๋ค. @samttern ๊ฐ์ฌํฉ๋๋ค. ๋์์ด ๋ฉ๋๋ค!
์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ค์ ๋ก ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒ์ ์ฌ์ฉ์ ํ ํฐ์ ๋ํ ์ปค์คํ ํด๋ ์ ์ ํฌํจํ๋ Cloud Functions ๋ฐ Firestore ์์ฒญ์ ํ ์คํธํ๋ ๊ฒ์ ๋๋ค. Firebase ์ฝ์์ ๊ท์น ํ๋ ์ด๊ทธ๋ผ์ด๋์์ Firestore๋ฅผ ์ฌ์ฉํ์ฌ ์ผ์ข ์ ๋ง์ถค ํด๋ ์์ ํ ์คํธํ ์ ์์ง๋ง ๋ณธ๊ฒฉ์ ์ธ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ก ์ ์ผ๋ก ์ฌ์ฉ์ ํ ํฐ๊ณผ ๊ด๋ จํ์ฌ ํ ์คํธํ๋ ๋ฐฉ์์ผ๋ก ํจ์ฌ ๋ ๋ง์ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
๋ถ๋ช ํ ํ์๋ฉด, ์ฐ๋ฆฌ๋ ์ค์ ์๋น์ค ์๋ํฌ์ธํธ๋ฅผ ์๋ฎฌ๋ ์ดํธํ๋ ๋ณธ๊ฒฉ์ ์ธ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ์ ์ ๋ ํ๊ณ ์์ต๋๋ค(๊ฐ๋ฅํ ๊ฒฝ์ฐ). ์ฐ๋ฆฌ๋ ๋ ์ด์ ์ด์ ์๊ฒฌ์ด ์ ์ํ
@samtstern ์ ๋ฃ๊ธฐ ์ข์ต๋๋ค(์ฌ์ฉ์ ์ง์ ํด๋ ์๊ณผ ํจ๊ป, ํ์ฌ ํตํฉ๊ณผ ํจ๊ป ์์ฃผ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์). ์งํ ์ํฉ/ETA๋ฅผ ํ์ธํ ์ ์๋ ๊ณณ์ด ์์ต๋๊น?
@fandy no ์ฃ์กํฉ๋๋ค ์์ง ๊ณต์ ํ ๋ด์ฉ์ด ์์ต๋๋ค...
Sam์๊ฒ ๊ฐ์ฌํฉ๋๋ค. ํ์ฌ ์๋์ผ๋ก ๋ชจ๋ ํ
์คํธ๋ฅผ ์ํํ๊ณ ์์ต๋๋ค.
Auth ๋ชจ์ ์์ด e2e ํ
์คํธ๋ฅผ ์์ฑํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
2020๋ 8์ 26์ผ ์์์ผ 14:32 Sam Stern [email protected]์์ ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค.
>
>
@fandy https://github.com/fandy ์ฃ์กํฉ๋๋ค.
์์ง ๊ณต์ ...โ
์ด ์ค๋ ๋์ ๊ฐ์ ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ ์์ต๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/firebase/firebase-tools/issues/1677#issuecomment-680850282 ,
๋๋ ๊ตฌ๋ ์ทจ์
https://github.com/notifications/unsubscribe-auth/AABU35UAQDBYEXKKINJSM43SCT6E7ANCNFSM4I27PTFA
.--
์๋ถ
๋์ฝ์ค ์นด์น์นด๋์ค
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ธ๋ผ์ฐ์ ์์ @firebase/testing ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์คํํ์ต๋๋ค. ์ ๋ง ํจ๊ณผ๊ฐ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๊ฐ ํธ์ง๋ ์ฒญํฌ๋ฅผ ๋ณต์ฌํ๊ธฐ ์ํด @firebase/testing source๋ฅผ mangleํฉ๋๋ค.
import firebase from "firebase/app"
import * as component from "@firebase/component"
import * as util from "@firebase/util"
import { __awaiter, __generator } from "tslib"
function createUnsecuredJwt(auth) {
// Unsecured JWTs use "none" as the algorithm.
var header = {
alg: 'none',
kid: 'fakekid'
};
// Ensure that the auth payload has a value for 'iat'.
auth.iat = auth.iat || 0;
// Use `uid` field as a backup when `sub` is missing.
auth.sub = auth.sub || auth.uid;
if (!auth.sub) {
throw new Error("auth must be an object with a 'sub' or 'uid' field");
}
// Unsecured JWTs use the empty string as a signature.
var signature = '';
return [
util.base64.encodeString(JSON.stringify(header), /*webSafe=*/ false),
util.base64.encodeString(JSON.stringify(auth), /*webSafe=*/ false),
signature
].join('.');
}
function initializeApp(accessToken, options) {
var _this = this;
var app = firebase.initializeApp(options);
if (accessToken) {
var mockAuthComponent = new component.Component('auth-internal', function () {
return ({
getToken: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
return [2 /*return*/, ({ accessToken: accessToken })];
}); }); },
getUid: function () { return null; },
addAuthTokenListener: function (listener) {
// Call listener once immediately with predefined accessToken.
listener(accessToken);
},
removeAuthTokenListener: function () { }
});
}, "PRIVATE" /* PRIVATE */);
app._addOrOverwriteComponent(mockAuthComponent);
}
return app;
}
export function initializeTestApp(options) {
let accessToken = undefined
if (options.auth !== undefined) {
accessToken = createUnsecuredJwt(options.auth)
}
return initializeApp(accessToken, options)
}
์ด์ ์ฑ ๋ธ๋ผ์ฐ์ ์ธก ์ฝ๋์์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
let app
if (dev) {
app = initializeTestApp({projectId: "test", auth: {uid: "testuser"}})
app.firestore().settings({
host: "localhost:8080",
ssl: false,
})
} else {
app = firebaseProduction.initializeApp({ firebase config here })
app.firestore().settings({ firestore config here })
}
window.firebase = app
์ ์๋ํฉ๋๋ค! ์ด์ ๊ฐ๋ฐ ์ค์ผ ๋ ์๋ฎฌ๋ ์ดํฐ๊ฐ "testuser"๋ผ๊ณ ์๊ฐํ๋ ๋ก์ปฌ ๊ฐ์ง ์ฌ์ฉ์๊ฐ ์์ต๋๋ค(firestore ๋ณด์ ๊ท์น ํ ์คํธ ๊ฐ์ด๋์์ ๋ณด์ฌ ์ฃผ๋ ๊ฒ์ฒ๋ผ).
๋ด๊ฐ ์ฌ์ฉํ๋ ๋ ๋ค๋ฅธ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ธ์ฆ์ ์คํ ํ๋ ๊ฒ์ ๋๋ค(ํ ์คํธ๋ฅผ ์ํด ์์ฑ๋ ๊ฐ์ง ์ฌ์ฉ์๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค).
TypeScript ์:
import type { User as AuthUser } from '@firebase/auth-types'
// not importing a type, but a module of types
import { auth as authTypes} from 'firebase/app'
type Auth = authTypes.Auth
export const authStub = {
getUser(uid: string) {
// for uids like `testuser1234uid`
let n = uid ? uid.replace("testuser", '').replace("uid", '') : ''
return Promise.resolve({
uid,
email: `test.user${n}@foo.com`,
emailVerified: true,
providerData: [{
providerId: 'google.com',
email: `test.user${n}@foo.com`,
uid: `testuser${n}provideruid`,
phoneNumber: null,
displayName: `Test User ${n}`.trim(),
photoURL: 'https://thispersondoesnotexist.com/image',
}],
metadata: {
// https://firebase.google.com/docs/reference/admin/node/admin.auth.UserMetadata
createTime: new Date().toUTCString(),
lastSignInTime: new Date().toUTCString()
},
customClaims: {
username: `testuser${n}`
}
})
},
deleteUser(uid: string) {
return Promise.resolve()
},
async updateUser(uid: string, data: AuthUser) {
let user = await this.getUser(uid)
return { ...user, data }
},
setCustomUserClaims(uid: string, customUserClaims: Object): Promise<void> {
return Promise.resolve()
}
}
export const auth = <Auth><unknown>authStub
๋ํ auth.token
๊ฐ ์๋ฎฌ๋ ์ดํธ๋์ง ์์ผ๋ฏ๋ก ๊ท์น์ ์์ ํ์ญ์์ค. ์๋ฅผ ๋ค์ด:
const rules = fs.readFileSync(__dirname + '/src/firebase/firestore/firestore.rules', 'utf8')
const modifiedRules =
rules
.replace(/request\.auth\.token\.email_verified/g, "true")
.replace(/request\.auth\.token\.firebase\.sign_in_provider/g, "'password'")
await firebase.loadFirestoreRules({ projectId, rules: modifiedRules })
๊ทธ๊ฒ์ ๋๋ฅผ ์ํด ์ ์๋ํฉ๋๋ค. ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋คโฆ
์ด ์ค๋ ๋๋ฅผ ํ๋ก์ฐํ๊ณ Firebase ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ์ ์ํ ํ ์คํฐ๊ฐ ๋๊ณ ์ถ๋ค๋ฉด ๋ค์ ๋จ๊ณ๋ฅผ ๋ฐ๋ฅด์ธ์.
์ด๊ธฐ ๋จ๊ณ์ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํด ๋ณด๊ณ ํผ๋๋ฐฑ์ ์ ๊ณตํ๋ ๋ฐ ์ง์งํ๊ฒ ๊ด์ฌ์ด ์๋ ๊ฒฝ์ฐ์๋ง ์ด ์์ ์ ์ํํ์ธ์! ๋ฒ๊ทธ๊ฐ ์๊ณ ์ค์ ์ ์ผ๋ถ๊ฐ ์ด๋ ค์ธ ์ ์์ง๋ง ๊ทํ์ ์๊ฐ์ ์๊ณ ์ถ์ต๋๋ค.
@samttern ๋ฐ๊ฐ์ด ์์์ ๋๋ค! ํด๋ณด๊ณ ์ถ์ง๋ง ์ฃผ๋ง๊น์ง ํ์ฌ ํ๋ก์ ํธ๋ก ํ๋ก๋์ ์ ๋ค์ด๊ฐ ์์ ์ด๋ฏ๋ก ํ์ฌ๋ก์๋ ๊ทธ๊ฒ์ ๊ฐ์ง๊ณ ๋ ์ฌ์ ๊ฐ ์์ต๋๋ค. ๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ ์ํ์ ๋ฑ๋กํ ์์ ์ ๋๋ค. :) ํ๋ฅญํ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
100% ์ด๊ฒ์ ์๋ํ๊ณ ์ถ์ดํ ๊ฒ์ ๋๋ค! ๋น์ ์ ๋จ์ ์!
@samttern ์ ๊ทธ๊ฒ์ ์๋ํ๊ณ ๋ด๊ฐ ํ ์ ์๋ ๋ชจ๋ ๊ฒ์ ๋์ธ ์ ์๊ธฐ๋ฅผ ๊ณ ๋ํ๊ณ ์์ต๋๋ค!
Android์์ ๋ก์ปฌ๋ก ๊ธฐ๋ฅ์ ํ ์คํธํ๋ ค๋ฉด ์ธ์ฆ ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ธ์ฆ ์ปจํ ์คํธ๋ ํญ์ null์ ๋๋ค.
์ข์ ์์์ ๋๋ค. ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ ์๋ก์ด 8.14.0 ๋ฆด๋ฆฌ์ค์ ์ผ๋ถ์ ๋๋ค! ๐๐
๊ณ ์ํ ์น๊ตฌ๋ค๊ณผ @samtstern ์๊ฒ ๊ฐ์ฌํฉ๋๋ค ๐ช
๋ฉ์ง ๋ ์๋ค!
๋ ๊ทธ๋ฅ ๋ฉ์ ์ ! Auth ์๋ฎฌ๋ ์ดํฐ๋ @yuchenshi ์์ 99% ๊ตฌ์ถํ์ต๋๋ค... ๊ทธ๋์ ๊ทธ๊ฐ ๊นจ์ด๋ฌ์ ๋ ์ด ๋ฌธ์ ๋ฅผ ๋ซ๋ ์๊ด์
์ด ์๋ก์ด ์๋ฎฌ๋ ์ดํฐ์ ๋ํ ๋ฌธ์๊ฐ ์์ต๋๊น? (ํด๋ผ์ด์ธํธ ์ค์น, ๊ตฌ์ฑ ๋ฐฉ๋ฒ ๋ฑ)
PS ์ด๊ฒ์ ๋ํ ๋ชจ๋ ๋ ธ๊ณ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๋ฅผ ์ํด ๋ชจ๋ ์ข ๋ฅ์ ๋ฉ์ง ๊ฒ๋ค์ ๊ฐ๋ฅํ๊ฒ ํ ๊ฒ์ ๋๋ค.
@nicoburns ๊ณง! ๊ณต์ ๋ฐํ, ๋ฌธ์ ๋ฐ ๋ชจ๋ ์ข์ ๊ฒ๋ค์ด ๊ณง ์ ๊ณต๋ ์์ ์ ๋๋ค.
์ข์ ์์! :) ๋นจ๋ฆฌ ์๋ํด๋ณด์ธ์ :)
๋น์ ์ด ์ด๊ฒ์ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ผ๋ฏ๋ก ์์ ์ผ๋ก ์๋ผ ๋ด ์๋ค.
**๋ป๋ปํ ํ๋ฌ๊ทธ: ์ค๋ ๋์ค์ "Firebase Emulator ์ ํ๊ตฐ์ ์ฌ์ฉํ์ฌ CI๋ฅผ ์ค์ ํ๋ ๋ฐฉ๋ฒ"์ ๋ํ ์ธ์ ๋ ์งํ ์ค์ ๋๋ค. ์ธ์ ์ผ์ ์์ ๊ทธ๊ฒ์ ์ฐพ๋ ๊ฒ์ ๋ ์๋ฅผ ์ํ ์ฐ์ต์ผ๋ก ๋จ๊ฒจ๋ก๋๋ค.
_์ถ์ . Auth Emulator๋ ๋ฌผ๋ก ํ์ํฌ์ด๊ธฐ ๋๋ฌธ์ 99%์ ํฌ๋ ๋ง์ ๋ฐ์ ์๋ ์์ต๋๋ค. Firebase์ ๋ค์ํ ์ฌ๋๋ค๊ณผ Firebase ๊ฐ๋ฐ์(๊ทํ)๋ ์ฌ๊ธฐ์ ํฐ ์ญํ ์ ํ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค!_
@yuchenshi Firestore ์๋ฎฌ๋ ์ดํฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ข ๋ฃ ์ ์์ฑ๋ ์ฌ์ฉ์๋ฅผ ๋ด๋ณด๋ผ ์ ์์ต๋๊น?
@vdjurdjevic ์์ง, ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค.
์ด๊ฒ์ ์ ๋ง ์ธ๊ธฐ ์๋ ๋ฌธ์ ์ด๋ฉฐ ๋ชจ๋ ์ ๋ฐ์ดํธ๋ 50-100๋ช ์๊ฒ ์๋ฆฝ๋๋ค. ์ด์ Auth ์๋ฎฌ๋ ์ดํฐ๋ฅผ ์ถ์ํ์ผ๋ฏ๋ก ํฅํ ์ ๋ฐ์ดํธ์์ ์ด ๋ฌธ์ ๋ฅผ ์ ๊ธ ๊ฒ์ ๋๋ค. ์ง๋ฌธ, ๋ฒ๊ทธ ๋๋ ๊ธฐ๋ฅ ์์ฒญ์ด ์๋ ๊ฒฝ์ฐ ์ ๋ฌธ์ ๋ฅผ ์์ํ์ธ์!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ฐ๋ฆฌ๋ ์์ ํ ์ธ์ฆ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ด์ฌํ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค.
๋ชจ๋๊ฐ ์ํ๋. ์ง๊ธ ์ ๊ณตํ ์ ์๋ ์ผ์ ์ ์์ง๋ง ์ฐ์ ์์๊ฐ ๋์ต๋๋ค.
์ฐ๋ฆฌ๋ฅผ ์ํด.
2020๋ 5์ 22์ผ ๊ธ์์ผ ์ค์ 8์ 12๋ถ์ ChuckB [email protected]์์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ์ต๋๋ค.