Firebase-tools: 7.0.2๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„ "์˜ค๋ฅ˜ : ์ˆ˜์‹  JSON ์˜ค๋ธŒ์ ํŠธ์— client_email ํ•„๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค."

์— ๋งŒ๋“  2019๋…„ 06์›” 28์ผ  ยท  61์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: firebase/firebase-tools

[ํ•„์ˆ˜] ํ™˜๊ฒฝ ์ •๋ณด


firebase-tools : 7.0.2


ํ”Œ๋žซํผ : Oracle Linux Server 7.6, Node 10.15

[ํ•„์ˆ˜] ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค


"firebase-admin": "^ 8.2.0", "firebase-functions": "^ 3.0.2"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ https ํ•จ์ˆ˜๋ฅผ ์—๋ฎฌ๋ ˆ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

[ํ•„์ˆ˜] ์žฌํ˜„ ๋‹จ๊ณ„

firebase ํ•จ์ˆ˜๋กœ ๋ชจ๋“  https ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค

[ํ•„์ˆ˜] ์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘

์˜ค๋ฅ˜ ์—†์Œ (firebase-tools 7.0.0์€ ์˜ค๋ฅ˜ ์—†์Œ)

[ํ•„์ˆ˜] ์‹ค์ œ ํ–‰๋™

๊ธฐ๋Šฅ ์š”์ฒญ์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค.

firebase > โš   Error: The incoming JSON object does not contain a client_email field
    at JWT.fromJSON (/riderequest/functions/node_modules/google-auth-library/build/src/auth/jwtclient.js:165:19)
    at GoogleAuth.fromJSON (/riderequest/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:294:16)
    at GoogleAuth.getClient (/riderequest/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:476:52)
    at GrpcClient._getCredentials (/riderequest/functions/node_modules/google-gax/build/src/grpc.js:107:40)
    at GrpcClient.createStub (/riderequest/functions/node_modules/google-gax/build/src/grpc.js:223:34)
    at new FirestoreClient (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/v1/firestore_client.js:128:39)
    at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/index.js:315:26)
    at ClientPool.acquire (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/pool.js:61:35)
    at ClientPool.run (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/pool.js:114:29)
    at Firestore.request (/riderequest/functions/node_modules/@google-cloud/firestore/build/src/index.js:957:33)
โš   Your function was killed because it raised an unhandled error.
emulator-suite functions bug

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

_ ๋ฉด์ฑ… ์กฐํ•ญ : ์—ฌ๊ธฐ์— ๋‚ด ๋ฌธ์ œ๊ฐ€์ด ๋ฌธ์ œ์™€ ์–ด๋–ค ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ, ์ ์–ด๋„ ์ผ๋ถ€๋Š” ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๊ธฐ์— ๋‚ด ์ •๋ณด๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ._

firestore ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ผ๋ถ€ ๋ฌธ์„œ๋ฅผ ์ผ๊ด„ ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” firebase ํ•จ์ˆ˜์—์„œ ๋™์ผํ–ˆ์Šต๋‹ˆ๋‹ค. (๋ฐฐ์น˜์—†์ด ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค).

์ด๊ฒƒ์€ ์ฝœ ์Šคํƒ์ž…๋‹ˆ๋‹ค.

Unhandled error Error: The incoming JSON object does not contain a client_email field
>      at JWT.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\jwtclient.js:165:19)
>      at GoogleAuth.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:294:16)
>      at GoogleAuth.getClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:476:52)
>      at GrpcClient._getCredentials (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:107:40)
>      at GrpcClient.createStub (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:223:34)
>      at new FirestoreClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\v1\firestore_client.js:128:39)
>      at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:315:26)
>      at ClientPool.acquire (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:61:35)
>      at ClientPool.run (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:114:29)
>      at Firestore.readStream (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:995:26)

RESPONSE RECEIVED FROM FUNCTION: 500, {
  "error": {
    "status": "INTERNAL",
    "message": "INTERNAL"
  }
}

๋ช…๋ น ์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
firebase functions:shell

์ด ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

// Reference report in Firestore
const db = admin.firestore();

admin.initializeApp();

export const performMyCallableFirebaseFunction = (db,, { from, to }) => {
    return db.collection("collectionName").where("prop", "==", from).limit(500).get().then(snapshot => {
        if (snapshot.empty) return new Promise(resolve => resolve(`No docs found with prop: ${from}`));

        const batch = db.batch();
        snapshot.forEach(doc => batch.update(doc.ref, { prop: to }));

        return batch.commit();
    });
};
exports.myCallableFirebaseFunction = functions.https.onCall(data => performMyCallableFirebaseFunction(db, data.from, data.to));

๋‚˜๋Š” ์ค„์„ ๋ฐ”๊ฟจ๋‹ค
admin.initializeApp();
...์—
admin.initializeApp({ credential: admin.credential.applicationDefault() });
์ด์ œ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด ํ•จ์ˆ˜๋ฅผ ๋กœ์ปฌ๋กœ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

firebase functions:shell
firebase > myCallableFirebaseFunction({from: "foo", to: "bar"})

admin.credential.applicationDefault ()์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ชจ๋“  61 ๋Œ“๊ธ€

@noelmansour ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. 7.0.1 ์™€ 7.0.2 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://github.com/googleapis/google-auth-library-nodejs/issues/137

https://github.com/googleapis/google-auth-library-nodejs/blob/37bb8c7cd0a6501103274284d9cddd6816cc881e/src/auth/jwtclient.ts#L253

7.0.2 ์ดํ›„์—๋„์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

7.0.2๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์—ฌ ์ด๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ๊ณ„์ • ์ž๊ฒฉ ์ฆ๋ช…์„ ํ™•์ธํ–ˆ๊ณ  client_email ํ•„๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€์ด ์˜ค๋ฅ˜๋กœ ์ธํ•ด ์‹คํŒจํ•œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์‹คํ–‰ํ•˜๋ ค๋Š” ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋ฅผ ๊ณต์œ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ„๋‹จํ• ์ˆ˜๋ก ์ข‹์Šต๋‹ˆ๋‹ค.

@samtstern ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

import * as admin from 'firebase-admin';
admin.initializeApp();

import * as functions from 'firebase-functions';

export const testFunction = functions.https.onRequest(async (req, res) => {
  const request = await admin.firestore().doc('test/123').get();

  return request.ref.set({ test: 'random' })
    .then(() => res.send('ok!'))
    .catch((err) => res.status(500).send('error'));
});

admin.initializeApp() ํ˜ธ์ถœ ํ•  ๋•Œ ์„œ๋น„์Šค ๊ณ„์ •์„ ์„ค์ • ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

// this works
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

@wceolin ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ํ•จ์ˆ˜ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

$ npm list @google-cloud/firestore

์ด๊ฒƒ์€ ๋‚ด ๊ฒฐ๊ณผ์ด๋ฉฐ ๋ชจ๋“  ๊ฒƒ์ด ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

functions@ /tmp/tmp.ZkMEM0XGPF/functions
โ””โ”€โ”ฌ [email protected]
  โ””โ”€โ”€ @google-cloud/[email protected]

๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค : ๐Ÿค”

Screen Shot 2019-07-01 at 15 44 35

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ์˜ค๋ฅ˜ ์Šคํƒ ์ถ”์  ๊ณผ์ด ๊ธฐ๋Šฅ์—์„œ ๊ธธ์„ ๊ฑท๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/googleapis/gax-nodejs/blob/e1be4ebcc2287c61d5f1884033449e3b4e143242/src/grpc.ts#L141

์ด ๋ถ„๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 async _getCredentials(opts: ClientStubOptions) {
    if (opts.sslCreds) {
      return opts.sslCreds;
    }
    const grpc = this.grpc;
    const sslCreds = grpc.credentials.createSsl();
    const client = await this.auth.getClient();
    const credentials = grpc.credentials.combineChannelCredentials(
      sslCreds,
      grpc.credentials.createFromGoogleCredential(client)
    );
    return credentials;
  }

๋‚ด ์ฝ”๋“œ์—์„œ opts.sslCreds ์ด ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ์ด ๋ถ„๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    if (opts.sslCreds) {
      return opts.sslCreds;
    }

์ž๊ฒฉ ์ฆ๋ช…์„ ์กฐํ•ฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ๋˜ ๋‹ค๋ฅธ ์ง€์ ์ž…๋‹ˆ๋‹ค. ์ด์ œ ๋‚ด ์ฝ”๋“œ๊ฐ€ ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๊ณ  ๋‹น์‹ ์˜ ์ฝ”๋“œ๊ฐ€ ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ๊ฐ€๋Š” ์ด์œ ๋ฅผ ์•Œ์•„ ๋‚ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@wceolin ์€ node_modules ํด๋”์— ์ ‘๊ทผํ•˜์—ฌ createStub ์—์„œ options ๊ฐœ์ฒด๋ฅผ ์ธ์‡„ํ•˜๋Š” console.log() ํŒŒ์ผ์„ functions/node_modules/google-gax/build/src/grpc.js ๋กœ ํŽธ์ง‘ํ•˜์—ฌ createStub ๊ธฐ๋Šฅํ•˜๊ณ  ๋‹น์‹ ์ด ๋ณด๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ฃผ์„ธ์š”?

์ง€๊ธˆ๊นŒ์ง€ ๋„์™€ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@samtstern ์ด๊ฒƒ์ด ๋„์›€์ด๋˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์ฃผ๋ง ๋™์•ˆ package.json ๋ฐ node_modules๋กœ ๋งŽ์€ ์กฐ์ •์„ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. 7.0.2์—์„œ ๋” ์ด์ƒ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

npm list @google-cloud/firestore ์ถœ๋ ฅ์ด ์‚ฌ์šฉ์ž์˜ ์ถœ๋ ฅ๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ๋ง์— ๋‚ด node_modules ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ˆ„ํฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

@noelmansour ๊ทธ ๋ฉ”๋ชจ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๊นจ๋—ํ•œ ์„ค์ •์—์„œ ์žฌํ˜„ ํ•  ์ˆ˜์—†๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

@noelmansour ๋‚˜๋Š” ๋˜ํ•œ ๋‚ด node_modules , yarn.lock ์‚ญ์ œํ•˜๊ณ  ์ข…์†์„ฑ์„ ์ œ๊ฑฐํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€๋ณด๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ๋ถ€ํ„ฐ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@noelmansour ์ด๊ฒƒ์€ options ๊ฐœ์ฒด์—์„œ ์–ป์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

{
  "clientConfig": {},
  "port":443,
  "servicePath":"firestore.googleapis.com",
  "credentials":{},
  "projectId":"my-test-project",
  "firebaseVersion":"8.2.0",
  "libName":"gccl",
  "libVersion":"2.2.3 fire/8.2.0",
  "scopes":[
    "https://www.googleapis.com/auth/cloud-platform", 
    "https://www.googleapis.com/auth/datastore"
  ]
}

@wceolin ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚ด ๋ชจ์Šต (๊ทธ๋ฆฌ๊ณ  ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€)์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ๋„์›€์ด๋ฉ๋‹ˆ๋‹ค.

{
   "clientConfig":{},
   "port":8080,
   "servicePath":"localhost",
   "credentials":{},
   "projectId":"fir-dumpster",
   "firebaseVersion":"8.2.0",
   "libName":"gccl",
   "libVersion":"2.2.3 fire/8.2.0",
   "service":"firestore.googleapis.com",
   "sslCreds":{
      "callCredentials": {}
   },
   "customHeaders":{
      "Authorization":"Bearer owner"
   },
   "scopes":[
      "https://www.googleapis.com/auth/cloud-platform",
      "https://www.googleapis.com/auth/datastore"
   ]
}

๋ณด์‹œ๋‹ค์‹œํ”ผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—ฌ์ „ํžˆ ํ”„๋กœ๋•์…˜ ์•ก์„ธ์Šค๋ฅผ ์‹œ๋„ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ํ•จ์ˆ˜ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€์ด๋ฅผ ์ˆ˜ํ–‰ ํ•  ๊ถŒํ•œ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

Firestore ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋„ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? Firestore ์—๋ฎฌ๋ ˆ์ดํ„ฐ์— ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์‹ค์ œ๋กœ ํ”„๋กœ๋•์…˜ Firestore์— ์ž‘์„ฑ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์˜ค, ๋“œ๋””์–ด ์ด๊ฑธ ์žฌํ˜„ ํ•  ์ˆ˜์žˆ์—ˆ์Šต๋‹ˆ๋‹ค! firebase emulators:start --only functions ์‹คํ–‰ํ•˜๋ฉด Firestore์— ์“ฐ๊ธฐ๋ฅผ ์‹œ๋„ํ•˜๋ฉด์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

โš   The Cloud Firestore emulator is not running so database operations will fail with a 'default credentials' error.

๋” ์ด์ƒ ์ •ํ™•ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ (์˜ค๋ฅ˜๋Š” client_email์— ๊ด€ํ•œ ๊ฒƒ์ž„) ํƒ์ง€๋Š” ์—ฌ์ „ํžˆ ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„์ด ๊ฒฝ๊ณ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹ค์Œ์€ ๋„์›€์ด ๋  ์ˆ˜์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์ •๋ณด์ž…๋‹ˆ๋‹ค. ์ฃผ๋ง ๋™์•ˆ .zshrc์— firestore ์—๋ฎฌ๋ ˆ์ดํ„ฐ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๋ช…์‹œ ์ ์œผ๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

export FIRESTORE_EMULATOR_HOST="localhost:8080"

์ œ๊ฑฐํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ firebase emulators:start ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@noelmansour --debug ํ•ด๋‹น ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ  ์—ฌ๊ธฐ์— ๋กœ๊ทธ๋ฅผ txt ํŒŒ์ผ๋กœ ์ฒจ๋ถ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@samtstern ๋•Œ๋กœ๋Š” ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๋•์…˜์—์„œ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•˜๋Š” HTTP ํ•จ์ˆ˜๋ฅผ ๋กœ์ปฌ๋กœ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค (์ผ๋ฐ˜์ ์œผ๋กœ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ˆ˜ํ–‰). ๋‚˜๋Š” ์‚ฌ์šฉํ•˜๊ณ ์žˆ๋‹ค :

firebase serve --only functions --project myProjectAlias

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ทธ๋ ‡๊ฒŒ ์ž‘๋™ํ•ด์•ผํ•˜๋Š”์ง€ (์šฐ๋ฆฌ๊ฐ€ ํ”„๋กœ๋•์…˜์— ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ) ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์˜ˆ์ „์—๋Š” ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜…

@wceolin 6.8.0 ์ดํ›„ ๋ฒ„์ „์—์„œ ๋ฒ ์–ด initializeApp() ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•„์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋„ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋กœ๋•์…˜์„ ๋ณดํ˜ธํ•˜๋„๋ก ์˜ตํŠธ ์ธ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š”์ด ์˜ค๋ฅ˜๊ฐ€ ์ง€๊ธˆ ์–ด๋””์„œ ์˜ค๋Š”์ง€ ์•Œ๊ฒŒ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค!

@samtstern ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด FIRESTORE_EMULATOR_HOST ์„ ์„ค์ •ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ firebase emulators:start --debug ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ?

์˜ณ์€!

2019 ๋…„ 7 ์›” 1 ์ผ ์›”์š”์ผ ์˜คํ›„ 12:28 Noel Mansour [email protected] ์ž‘์„ฑ :

@samtstern https://github.com/samtstern ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด firebase๋ฅผ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.
emulators : start --debug with the FIRESTORE_EMULATOR_HOST not set, right?

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/firebase/firebase-tools/issues/1451?email_source=notifications&email_token=ACATB2WV27VPIODNLGFS4TLP5JLGBA5CNFSM4H4GTWI2YY3PNVWWK3TUL52HS4DFWSVREXG4393VMVORBW63LNDYMVXHJK
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ACATB2WG4EAD5KU7YRB5AUTP5JLGBANCNFSM4H4GTWIQ
.

์—ฌ๊ธฐ์žˆ์–ด.

์ฐธ๊ณ ๋กœ์ด ์ค„์—์„œ project-id๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค (์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค).
[2019-07-01T19:32:42.859Z] >>> HTTP REQUEST GET https://mobilesdk-pa.googleapis.com/v1/projects/<project-id>:getServerAppConfig

debug.txt

๋˜ํ•œ ์–ธ๊ธ‰ ํ•  ๊ฐ€์น˜๊ฐ€์žˆ๋Š” ๊ฒƒ์€ env ๋ณ€์ˆ˜๋ฅผ ๋‚ด ๋ณด๋‚ด์ง€ ์•Š๊ณ  [email protected]์—์„œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

โš   Error: Getting metadata from plugin failed with error: Header field "authorization" must have only a single value
    at Http2CallStream.call.on (/Users/noel/dev/snowble/functions/node_modules/@grpc/grpc-js/build/src/call.js:68:41)
    at emitOne (events.js:121:20)
    at Http2CallStream.emit (events.js:211:7)
    at process.nextTick (/Users/noel/dev/snowble/functions/node_modules/@grpc/grpc-js/build/src/call-stream.js:71:22)
    at _combinedTickCallback (internal/process/next_tick.js:132:7)
    at process._tickCallback (internal/process/next_tick.js:181:9)
โš   Your function was killed because it raised an unhandled error.

ํ•ด๋‹น ๋กœ๊ทธ์— ๋Œ€ํ•ด @noelmansour ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ฝ”๋“œ๋„ ๋ณด์—ฌ ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๋‚ด ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๊ณต์œ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ๊นŒ๋‹ค ๋กญ๊ณ  ์ง€๊ธˆ์€ ๊ฒฉ๋ฆฌ ์ƒํƒœ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ์žฌํ˜„๋˜๋Š”์ง€ ํ™•์ธํ•  ์‹œ๊ฐ„์ด ์—†์ง€๋งŒ ์—ฌ๊ธฐ์— ๋‚ด๊ฐ€ ์‹คํ–‰ ํ•œ hello ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts :

require('./common'); // this should always be first in this file

export * from './debug'
// other exports for other functions

common.ts :

import * as admin from 'firebase-admin';

export const app = admin.initializeApp();

debug.ts :

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
import {app} from "./common";

export const hello = functions.https.onRequest(async (req, resp) => {
    const firestore = app.firestore();
    const users = await firestore.collection('users').get();
    console.log('empty users collection? ' + users.empty);
    resp.sendStatus(200);
});

package.json :

{
  "name": "functions",
  "scripts": {
    "lint": "tslint --project tsconfig.json",
    "build": "tsc",
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase functions:shell",
    "emulators": "npm run build && firebase emulators:start",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "8"
  },
  "main": "lib/index.js",
  "dependencies": {
    "@google-cloud/tasks": "^1.1.0",
    "@types/jsonwebtoken": "^8.3.2",
    "@types/request-promise": "^4.1.42",
    "firebase-admin": "^8.2.0",
    "firebase-functions": "^3.0.2",
    "request": "^2.88.0",
    "request-promise": "^4.2.4"
  },
  "devDependencies": {
    "tslint": "^5.12.0",
    "typescript": "^3.2.2"
  },
  "private": true
}

@noelmansour ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋ฒ„๊ทธ๋ฅผ ๋“œ๋Ÿฌ๋ƒˆ๋‹ค. ์ด ๋‘ ๊ฐ€์ง€๋Š” ๋™์ผํ•ด์•ผํ•˜์ง€๋งŒ ๋‹ค์Œ์€ ์•„๋‹™๋‹ˆ๋‹ค.

์˜ต์…˜ 1

admin.initializeApp();
const firestore = admin.firestore();

์˜ต์…˜ 2

const app = admin.initializeApp();
const firestore = app.firestore();

๋„ค, ๊ทธ๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ๊ทธ๊ฒƒ์„ ๊ณ ์ณค์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ!

๋˜ํ•œ Error: The incoming JSON object does not contain a client_email field ์˜ค๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ ์น  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์ฝ”๋“œ :

import { initializeApp } from 'firebase-admin';

// Initiate Firebase app
export const app = initializeApp();
export const db = app.firestore();
export const auth = app.auth();

๋˜ ๋‹ค๋ฅธ ์‹œ๋„ :

import { initializeApp, firestore, auth as defAuth } from 'firebase-admin';

// Initiate Firebase app
export const app = initializeApp();
export const db = firestore();
export const auth = defAuth();

๋˜ ๋‹ค๋ฅธ ์‹œ๋„ :

import * as admin from 'firebase-admin';

// Initiate Firebase app
export const app = admin.initializeApp();
export const db = admin.firestore();
export const auth = admin.auth();

@JFGHT ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? --debug ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…๋ น ๋ฐ ์‹คํ–‰ ๋กœ๊ทธ๋ฅผ ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

_ ๋ฉด์ฑ… ์กฐํ•ญ : ์—ฌ๊ธฐ์— ๋‚ด ๋ฌธ์ œ๊ฐ€์ด ๋ฌธ์ œ์™€ ์–ด๋–ค ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ, ์ ์–ด๋„ ์ผ๋ถ€๋Š” ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๊ธฐ์— ๋‚ด ์ •๋ณด๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ._

firestore ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ผ๋ถ€ ๋ฌธ์„œ๋ฅผ ์ผ๊ด„ ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” firebase ํ•จ์ˆ˜์—์„œ ๋™์ผํ–ˆ์Šต๋‹ˆ๋‹ค. (๋ฐฐ์น˜์—†์ด ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค).

์ด๊ฒƒ์€ ์ฝœ ์Šคํƒ์ž…๋‹ˆ๋‹ค.

Unhandled error Error: The incoming JSON object does not contain a client_email field
>      at JWT.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\jwtclient.js:165:19)
>      at GoogleAuth.fromJSON (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:294:16)
>      at GoogleAuth.getClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-auth-library\build\src\auth\googleauth.js:476:52)
>      at GrpcClient._getCredentials (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:107:40)
>      at GrpcClient.createStub (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\google-gax\build\src\grpc.js:223:34)
>      at new FirestoreClient (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\v1\firestore_client.js:128:39)
>      at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:315:26)
>      at ClientPool.acquire (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:61:35)
>      at ClientPool.run (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\pool.js:114:29)
>      at Firestore.readStream (D:\thdk\Projects\timesheets\functions\node_modules\firebase-admin\node_modules\@google-cloud\firestore\build\src\index.js:995:26)

RESPONSE RECEIVED FROM FUNCTION: 500, {
  "error": {
    "status": "INTERNAL",
    "message": "INTERNAL"
  }
}

๋ช…๋ น ์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
firebase functions:shell

์ด ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

// Reference report in Firestore
const db = admin.firestore();

admin.initializeApp();

export const performMyCallableFirebaseFunction = (db,, { from, to }) => {
    return db.collection("collectionName").where("prop", "==", from).limit(500).get().then(snapshot => {
        if (snapshot.empty) return new Promise(resolve => resolve(`No docs found with prop: ${from}`));

        const batch = db.batch();
        snapshot.forEach(doc => batch.update(doc.ref, { prop: to }));

        return batch.commit();
    });
};
exports.myCallableFirebaseFunction = functions.https.onCall(data => performMyCallableFirebaseFunction(db, data.from, data.to));

๋‚˜๋Š” ์ค„์„ ๋ฐ”๊ฟจ๋‹ค
admin.initializeApp();
...์—
admin.initializeApp({ credential: admin.credential.applicationDefault() });
์ด์ œ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด ํ•จ์ˆ˜๋ฅผ ๋กœ์ปฌ๋กœ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

firebase functions:shell
firebase > myCallableFirebaseFunction({from: "foo", to: "bar"})

admin.credential.applicationDefault ()์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฟก๋ฟก

concurrently --kill-others 'GOOGLE_APPLICATION_CREDENTIALS=service-account.json firebase serve --only functions' 'tsc --project ./ --watch'

๋กœ๊ทธ์— ๊ด€ํ•ด์„œ๋Š” ์˜ค๋Š˜์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค!

๋‚˜๋Š” ์ค„์„ ๋ฐ”๊ฟจ๋‹ค
admin.initializeApp();
...์—
admin.initializeApp({ credential: admin.credential.applicationDefault() });

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์„ ํ†ตํ•ด ๋กœ์ปฌ์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
firebase serve --only functions

์ด๊ฒƒ์ด ์ƒ์‚ฐ์— ์•ˆ์ „ํ•œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์—์„œ ํ”„๋กœ๋•์…˜์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•œ ๊ด€๋ฆฌ์ž ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฌ์ง€๋งŒ ์–ด์จŒ๋“  ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค.

@ ralphsmith80 aah ์•„๋งˆ ๋งž์Šต๋‹ˆ๋‹ค.

์ž๋™์œผ๋กœ ์ž๊ฒฉ ์ฆ๋ช… ์ฐพ๊ธฐ
GCP ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด (ADC)๋ผ๋Š” ์ „๋žต์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ „๋žต์€ ๋‹ค์Œ ์ˆœ์„œ๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ € ADC๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜ GOOGLE_APPLICATION_CREDENTIALS๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜๋ฉด ADC๋Š” ๋ณ€์ˆ˜๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์„œ๋น„์Šค ๊ณ„์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ADC๋Š” Compute Engine, Kubernetes Engine, App Engine, Cloud Functions๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ์„œ๋น„์Šค ๊ณ„์ •์„ ํ•ด๋‹น ์„œ๋น„์Šค์—์„œ ์‹คํ–‰๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ADC๊ฐ€ ์œ„์˜ ์ž๊ฒฉ ์ฆ๋ช… ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด ์ „๋žต์€ ํ…Œ์ŠคํŠธ ๋ฐ ์‹คํ—˜์‹œ ์œ ์šฉํ•˜์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ์ค‘์ธ ์ž๊ฒฉ ์ฆ๋ช…์„ ์‹๋ณ„ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : https://cloud.google.com/docs/authentication/production

๋‚˜๋Š” ์ค„์„ ๋ฐ”๊ฟจ๋‹ค
admin.initializeApp();
...์—
admin.initializeApp({ credential: admin.credential.applicationDefault() });

์ด ๋ฐฉ๋ฒ•์€ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ์˜ค๋ฅ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
      at GoogleAuth.getApplicationDefaultAsync (/Users/otanriverdi/Projects/socialpong/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19)
     at process._tickCallback (internal/process/next_tick.js:68:7)

# 1454์—์„œ ์–ธ๊ธ‰ ํ•œ๋Œ€๋กœ ์Šคํ† ์–ด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

admin.initializeApp();
const db = admin.firestore(); 

initializeApp ์ถ”๊ฐ€ ๋œ ์ž๊ฒฉ ์ฆ๋ช…์œผ๋กœ ์œ„์˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๊ฒƒ ์—†์ด๋„ ๋‚˜๋Š” ์—ฌ์ „ํžˆ ์–ป๊ณ ์žˆ๋‹ค.

Error: The incoming JSON object does not contain a client_email field
      at JWT.fromJSON (/Users/otanriverdi/Projects/socialpong/functions/node_modules/google-auth-library/build/src/auth/jwtclient.js:165:19)
      at GoogleAuth.fromJSON (/Users/otanriverdi/Projects/socialpong/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:294:16)
      at GoogleAuth.getClient (/Users/otanriverdi/Projects/socialpong/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:476:52)
      at GrpcClient._getCredentials (/Users/otanriverdi/Projects/socialpong/functions/node_modules/google-gax/build/src/grpc.js:107:40)
      at GrpcClient.createStub (/Users/otanriverdi/Projects/socialpong/functions/node_modules/google-gax/build/src/grpc.js:223:34)
      at new FirestoreClient (/Users/otanriverdi/Projects/socialpong/functions/node_modules/@google-cloud/firestore/build/src/v1/firestore_client.js:128:39)
      at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory] (/Users/otanriverdi/Projects/socialpong/functions/node_modules/@google-cloud/firestore/build/src/index.js:315:26)
      at ClientPool.acquire (/Users/otanriverdi/Projects/socialpong/functions/node_modules/@google-cloud/firestore/build/src/pool.js:61:35)
      at ClientPool.run (/Users/otanriverdi/Projects/socialpong/functions/node_modules/@google-cloud/firestore/build/src/pool.js:114:29)
      at Firestore.readStream (/Users/otanriverdi/Projects/socialpong/functions/node_modules/@google-cloud/firestore/build/src/index.js:995:26)

๊ธฐ๋ณธ ์ž์Šต์„œ (ํŠœํ† ๋ฆฌ์–ผ์€ 2019 ๋…„ 6 ์›”๋ถ€ํ„ฐ)์—์„œ ์ด์™€ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ์ด ์˜ค๋ฅ˜๋Š” ๋งค์šฐ ์ƒˆ๋กญ์Šต๋‹ˆ๋‹ค.

INDEX.JS :

```const functions = require ( 'firebase-functions');
const admin = require ( 'firebase-admin');
admin.initializeApp ();

admin.firestore()
    .collection('screams')
    .add(newScream)
    .then(doc => {
        res.json({message: `document ${doc.id} created successfully`});
    }) 
    .catch(err => {
        res.status(500).json({ error: 'oops, something went wrong'});
        console.error(err);
    });

});


Postman์—์„œ ์—”๋“œ ํฌ์ธํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

"์˜ค๋ฅ˜": "์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."

์ฝ˜์†”์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

ํ•จ์ˆ˜ : "createScream"์‹คํ–‰ ์‹œ์ž‘
์˜ค๋ฅ˜ : ์ˆ˜์‹  JSON ๊ฐœ์ฒด์— client_email ํ•„๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

ํŠœํ† ๋ฆฌ์–ผ์€ FreeCodeCamp์—์„œ์ž…๋‹ˆ๋‹ค - https://www.youtube.com/watch?v=m_u6P5k0vP0

Firebase ์ฝ˜์†”> ์„ค์ • (ํ†ฑ๋‹ˆ ๋ฐ”ํ€ด ์•„์ด์ฝ˜)> ์‚ฌ์šฉ์ž ๋ฐ ๊ถŒํ•œ> ์„œ๋น„์Šค ๊ณ„์ •

์ƒˆ ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค.

ํ”„๋กœ์ ํŠธ ํด๋”์— json์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

var admin = require("firebase-admin");

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://lts-profile.firebaseio.com"
});

์„œ๋น„์Šค ๊ณ„์ • json ํŒŒ์ผ์€ ํ”„๋กœ์ ํŠธ์—์„œ Firebase ์„œ๋น„์Šค ๋ฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋กํ•ฉ๋‹ˆ๋‹ค.
ํ•ญ์ƒ ๋น„๊ณต๊ฐœ ์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค. .gitignore์— ํŒŒ์ผ ํฌํ•จ

Firebase ์ฝ˜์†”> ์„ค์ • (ํ†ฑ๋‹ˆ ๋ฐ”ํ€ด ์•„์ด์ฝ˜)> ์‚ฌ์šฉ์ž ๋ฐ ๊ถŒํ•œ> ์„œ๋น„์Šค ๊ณ„์ •

์ƒˆ ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค.

ํ”„๋กœ์ ํŠธ ํด๋”์— json์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

var admin = require("firebase-admin");

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://lts-profile.firebaseio.com"
});

์„œ๋น„์Šค ๊ณ„์ • json ํŒŒ์ผ์€ ํ”„๋กœ์ ํŠธ์—์„œ Firebase ์„œ๋น„์Šค ๋ฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋กํ•ฉ๋‹ˆ๋‹ค.
ํ•ญ์ƒ ๋น„๊ณต๊ฐœ ์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค. .gitignore์— ํŒŒ์ผ ํฌํ•จ


๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค phtn, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ง€์นจ์„ ๋”ฐ๋ž์ง€๋งŒ ์ด์ œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Error: Error occurred while parsing your function triggers.

์ด์ƒํ•˜๊ฒŒ๋„ 'firebase deploy'๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ' https : //europe-west1-myapp.cloudfunctions.net/api / ...- localhost๊ฐ€ ์•„๋‹™๋‹ˆ๊นŒ?

์ด ๋‘ ๊ฐ€์ง€ ์‘๋‹ต์˜ ์กฐํ•ฉ์ด ํšจ๊ณผ๊ฐ€์žˆ์—ˆ์Šต๋‹ˆ๋‹ค! ๋„์™€ ์ฃผ์…”์„œ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

https://stackoverflow.com/questions/44626919/where-is-or-what-is-the-serviceaccountkey-json-is-the-node-js-sample-of-firebase?rq=1

https://stackoverflow.com/questions/42176453/google-app-engine-node-cannot-find-module-firebase-admin/42634321#42634321

serviceAccountKey.json์€ /functions ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

firebase deploy --only functions ๊ฐ€ ์™ธ๋ถ€์— ์žˆ์œผ๋ฉด ๋ถˆ๋งŒ์„ ์ œ๊ธฐํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‚ด serviceAccountKey.json์€ / functions ํด๋”์— ์žˆ์Šต๋‹ˆ๋‹ค (์•„๋ž˜ ๋งํฌ์˜ screen-grab ์ฐธ์กฐ).

์•ฑ์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.์ด ์„ธ ๊ฐ€์ง€๋ฅผ ๋ชจ๋‘ ๊ฐœ๋ณ„์ ์œผ๋กœ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋†“์น˜๊ณ ์žˆ๋Š” ๋ฏธ์นœ ๋‹จ์ˆœํ•œ ์ผ์ด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋””

ํ™”๋ฉด ์žก๊ธฐ :
Screenshot 2019-07-10 at 09 22 32

์šฐ๋ฆฌ ์ชฝ์—์„œ๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋ธ์—์„œ firebase๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

const firebaseInstance = admin.initializeApp ()
const firestoreInstance = firebaseInstance.firestore ()

์ด ๋ฌธ์ œ๋ฅผ ์ถ”์ ํ•˜๋Š” ๋ฐ ๋„์›€์ด๋˜๋Š” ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

์ด ์Šค๋ ˆ๋“œ์˜ ๋ชจ๋“  ์‚ฌ๋žŒ. ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. firebase-tools๋ฅผ 7.0.2์—์„œ 7.0.1๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๊ณ  ์™„์ „ํžˆ ๋‹ค๋ฅธ ์˜ค๋ฅ˜ (๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ๋กœ๋“œ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜)๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๊ณ„์†ํ•ด์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

gcloud auth application-default login

์ด๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@ryanhornberger ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const firebaseInstance = admin.initializeApp()
const firestoreInstance = admin.firestore() // I changed this line

๋‚˜๋Š” # 1459์— ์˜ค๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์ˆ˜์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@samtstern ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ด ์Šค๋ ˆ๋“œ์˜ ๋ชจ๋“  ์‚ฌ๋žŒ. ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. firebase-tools๋ฅผ 7.0.2์—์„œ 7.0.1๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๊ณ  ์™„์ „ํžˆ ๋‹ค๋ฅธ ์˜ค๋ฅ˜ (๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ๋กœ๋“œ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜)๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๊ณ„์†ํ•ด์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

gcloud auth application-default login

์ด๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” firebase-tools๋ฅผ 7.1๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ๋Š”๋ฐ ๋กœ์ปฌ์—์„œ 'firebase serve'๋ฅผ ์‹คํ–‰ํ•  ๋•Œ '๋™์ผํ•œ ์˜ค๋ฅ˜'๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ firebase์— ๋ฐฐํฌํ•˜๋ฉด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. 7.0.1๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ๋‚ด ์ง€์—ญ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

7.1๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ

์ˆ˜์ • ์ž‘์—… ์ค‘์ด์ง€๋งŒ ์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
https://github.com/firebase/firebase-tools/pull/1479

์ œ๋ฐœ ์ด๊ฑธ๋กœ ๋ถ™์–ด ์žˆ์–ด์š”, ์–ด๋–ค ๋ฐฉ๋ฒ• ์œผ๋กœ์š”?

7.0.1๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•ด๋„ ๋„์›€์ด๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์ด # 1479์— ๋ณ‘ํ•ฉ๋˜์—ˆ์œผ๋ฉฐ ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์— ํฌํ•จ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค ( 7.2.0 ).

์•ˆ๋…•ํ•˜์„ธ์š” @samtstern , ์ œ๊ฐ€ โ€‹โ€‹์ž˜๋ชปํ•˜๊ณ ์žˆ๋Š”

๋จผ์ € firebase emulators:exec "npm run test" ์‹คํ–‰ํ•  ๋•Œ ๋‹ค์Œ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

โš  The Cloud Firestore emulator is not running, so calls to Firestore will affect production.

๋ช…๋ น์˜ ์•ž๋ถ€๋ถ„์—์„œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

~/d/s/functions โฏโฏโฏ firebase emulators:exec "npm run test"                                                                                                                           โœ˜ 130
i  Starting emulators: ["functions","firestore"]
โœ”  functions: Using node<strong i="12">@8</strong> from host.
โœ”  functions: Emulator started at http://localhost:5001
i  firestore: Logging to firestore-debug.log
โœ”  firestore: Emulator started at http://localhost:8080
i  firestore: For testing set FIRESTORE_EMULATOR_HOST=localhost:8080

์‹ค์ œ๋กœ ํ”„๋กœ๋•์…˜ Firestore DB๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๊ฑฐ์ง“ ์Œ์„ฑ์ผ๊นŒ์š”?

๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. $GOOGLE_APPLICATION_CREDENTIALS ์„ค์ •ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ https://firebase.google.com/docs/functions/local-emulator#set_up_admin_credentials_optional ์— ๋”ฐ๋ผ firestore์—๋งŒ ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋ฏธ ์ถฉ๋ถ„ํ•œ ๊ถŒํ•œ์ด ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Cloud Firestore ๋ฐ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํŠธ๋ฆฌ๊ฑฐ์—๋Š” ์ด๋ฏธ ์ถฉ๋ถ„ํ•œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉฐ ์ถ”๊ฐ€ ์„ค์ •์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

admin.initializeApp(); ์‚ฌ์šฉํ•˜์—ฌ ๋งค๊ฐœ ๋ณ€์ˆ˜์—†์ด ๊ด€๋ฆฌ์ž SDK๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ž˜๋ชปํ•˜๊ณ ์žˆ๋Š” ์ž‘์—…์ผ๊นŒ์š”?

@noelmansour ์ด๊ฒƒ์„๋ณด๊ณ  master !) ๋‹น์‹ ์˜ ์ฃผ ํ•จ์ˆ˜ ํŒŒ์ผ์˜ ์ฝ”๋“œ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฑฐ์˜ ํ™•์‹คํ•˜๊ฒŒ ์œ„์Œ์„ฑ์ด์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ๊ณ ์ณ์•ผ ํ•  ์ค‘์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ๋งค์šฐ ์ตœ์†Œํ™”๋ฉ๋‹ˆ๋‹ค.

import * as admin from 'firebase-admin';

// this should happen before any function runs
admin.initializeApp();

export * from './authFunctions';
export * from './fitbit';
export * from './sleep'
export * from './scheduler';
export * from './debug'
export {scheduleFunction} from "./scheduler";

์‹ค์ œ๋กœ ๋‚ด ํ…Œ์ŠคํŠธ ์„ค์ •์— ๋ฌธ์ œ๊ฐ€์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. firebase emulators:start ์‹คํ–‰์‹œ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@noelmansour ํ…Œ์ŠคํŠธ๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ์ด ์Šค๋ ˆ๋“œ์˜ ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ŠคํŒธ ๋ฉ”์ผ์„ ๋ณด๋‚ด์ง€ ์•Š๋„๋ก์ด ๋ฌธ์ œ๋ฅผ ๋…ผ์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.>

์˜ˆ, ๋ฌผ๋ก ์ž…๋‹ˆ๋‹ค. ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. # 1530 ๊ฐœ์žฅ

์ด ์Šค๋ ˆ๋“œ์˜ ๋ชจ๋“  ์‚ฌ๋žŒ. ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. firebase-tools๋ฅผ 7.0.2์—์„œ 7.0.1๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๊ณ  ์™„์ „ํžˆ ๋‹ค๋ฅธ ์˜ค๋ฅ˜ (๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด๋ฅผ๋กœ๋“œ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜ค๋ฅ˜)๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๊ณ„์†ํ•ด์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

gcloud auth application-default login

์ด๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” firebase-tools๋ฅผ 7.1๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ๋Š”๋ฐ ๋กœ์ปฌ์—์„œ 'firebase serve'๋ฅผ ์‹คํ–‰ํ•  ๋•Œ '๋™์ผํ•œ ์˜ค๋ฅ˜'๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ firebase์— ๋ฐฐํฌํ•˜๋ฉด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. 7.0.1๋กœ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ๋‚ด ์ง€์—ญ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ด์–ด๋ฒ ์ด์Šค ๋ฒ„์ „์„ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋‚ด ํ˜„์žฌ ๋ฒ„์ „์€ 7.0.2์ด๊ณ  npm i [email protected] -g this ์„ค์น˜๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋‚ด ๋ฒ„์ „์€ 7.0.2์ž…๋‹ˆ๋‹ค. pls ๋„์›€์„ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•?

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ „์ฒด ํ”ฝ์Šค๋Š” 7.2.0 ์— ๋ฆด๋ฆฌ์Šค๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

npm install -g [email protected]

ํ•ด๋‹น ๋ฒ„์ „์—์„œ ์—ฌ์ „ํžˆ ์œ ์‚ฌํ•œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์ƒˆ ๋ฌธ์ œ๋ฅผ์—ฌ์‹ญ์‹œ์˜ค.

Firebase ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ npm install -g [email protected]์„ ์‹œ๋„ํ•˜์—ฌ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Screen Shot 2019-12-12 at 4 23 57 AM

Screen Shot 2019-12-12 at 4 21 30 AM

Firebase ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ npm install -g [email protected]์„ ์‹œ๋„ํ•˜์—ฌ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Screen Shot 2019-12-12 at 4 23 57 AM

Screen Shot 2019-12-12 at 4 21 30 AM

๋‹ค์Œ ์†”๋ฃจ์…˜์ด ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

// Create Firebase-adminsdk key

// Providing a service account object inline
admin.initializeApp({
    credential: admin.credential.cert({
        projectId: "<PROJECT_ID>",
        clientEmail: "foo@<PROJECT_ID>.iam.gserviceaccount.com",
        privateKey: "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n"
    })
});
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰