Cloud Storage에 업로드된 ZIP 파일 자동 배포 for Firebase

개요



Firebase에서 Cloud Storage에 ZIP 파일이 업로드되면 자동 배포하는 방법입니다.

복수의 파일을 정리해 업로드하고 싶지만 참조는 개별적으로 할 수 있는 것이 좋다…라고 하는 경우등에.
약간의 처리입니다만 의외로 스니펫이 발견되지 않았기 때문에 기사로 했습니다.

절차



Cloud Functions의 Cloud Storage 트리거를 활용합니다.
Cloud Functions 설정 및 초기화, 배포 등의 기본 단계는 시작 가이드를 참조하세요.
htps : // 푹 빠져라. 오, ぇ. 코 m / 드 cs / 훈 c 치온 s / 게 ts r d? hl = 그럼

프로젝트를 초기화한 후 index.js 를 다음과 같이 다시 작성합니다.

index.js
'use strict'

const functions = require('firebase-functions')
const mkdirp = require('mkdirp-promise')
const gcs = require('@google-cloud/storage')({keyFilename: 'service-account-credentials.json'})
const unzipper = require('unzipper')

const path = require('path')
const os = require('os')
const fs = require('fs')

/**
 * バケットで新しいオブジェクト(または既存オブジェクトの新しい世代)が正常に作成された場合に送信されます。
 * 既存のオブジェクトをコピーまたは再作成した場合にも送信されます。
 * アップロードが失敗した場合、このイベントはトリガーされません。
 */
exports.extractZip = functions.storage.object().onFinalize((object) => {

  // ZIPファイル以外は対象外
  if (!object.name.endsWith('.zip') || !object.contentType.includes('zip')) {
    console.log(`処理対象外のファイルです。name=${object.name},contentType=${object.contentType}`)
    return null
  }

  const baseName = path.basename(object.name, path.extname(object.name))
  const srcFile = gcs.bucket(object.bucket).file(object.name)
  const tmpDir = path.join(os.tmpdir(), baseName)
  const tmpFile = path.join(os.tmpdir(), path.basename(object.name))
  const dstBucket = gcs.bucket('gs://example') // 展開先のバケット名
  const dstDir = path.join('extract', baseName) // 展開先のディレクトリパス

  return mkdirp(path.dirname(tmpFile))
  .then(() => {
    return srcFile.download({destination: tmpFile})

  }).then(() => {
    console.log('Cloud StorageからローカルへZIPファイルをダウンロードしました。', tmpFile)

    return fs.createReadStream(tmpFile)
      .pipe(unzipper.Extract({path: tmpDir}))
      .on('close', () => {console.log('ZIPファイルを次のディレクトリへ展開しました。', tmpDir)})
      .promise()

  }).then(() => {
    let uploads = []
    fs.readdirSync(tmpDir).forEach(file => {
      uploads.push(
        dstBucket.upload(path.join(tmpDir, file), {destination: path.join(dstDir, file)})
      )
    })
    return Promise.all(uploads)

  }).then(() => {
    console.log('ローカルからCloud Storageへ展開後ファイル群をアップロードしました。', dstBucket.name)

    fs.unlinkSync(tmpFile)
    fs.readdirSync(tmpDir).forEach(file => {
      fs.unlinkSync(path.join(tmpDir, file))
    })
    fs.rmdirSync(tmpDir)
    console.log('ローカルの一時ファイルを削除しました。')
    return null

  }).then(() => {
    // TODO: 後続処理のキックなど
    return null
  })
})

필요한 패키지를 npm 로 추가합니다. 다음은 dependencies의 예입니다.

package.json
...
"dependencies": {
  "@google-cloud/storage": "^1.7.0",
  "firebase-admin": "~5.12.1",
  "firebase-functions": "^1.0.3",
  "mkdirp": "^0.5.1",
  "mkdirp-promise": "^5.0.1",
  "unzipper": "^0.9.2"
},
...

또한 배포하기 전에 Cloud Storage에 대한 액세스 권한이 있는 자격 증명 파일을 index.js와 동일한 functions 디렉터리에 저장합니다.
위의 예에서는 파일 이름을 service-account-credentials.json로 지정합니다.

Firebase 서비스 계정을 그대로 사용하는 경우 관리 콘솔 설정 > 서비스 계정 > 새 개인 키 생성을 통해 자격 증명 파일을 다운로드할 수 있습니다.

안내서에 설명된 대로 Cloud Functions for Firebase는 2018년 7월 현재 베타 버전으로 제공되므로 SLA에 적용되지 않습니다. 이용시에는 충분히 주의해 주십시오.

좋은 웹페이지 즐겨찾기