콘솔로 이동

Cloud Functions용 Firebase SDK 업그레이드 가이드: 베타에서 버전 1.0 이상으로 업그레이드

Cloud Functions용 Firebase SDK의 버전 1.0.0에는 몇 가지 중요한 API 변경사항이 있습니다. 주요한 변경사항으로 event.data 형식이 datacontext 매개변수로 교체되어 HTTP가 아닌 모든 비동기 함수에 영향이 있습니다. 단위 테스트 도우미 SDK firebase-functions-test에도 업데이트된 SDK를 사용할 수 있습니다. 자세한 내용은 단위 테스트 함수를 참조하세요.

Cloud Functions용 Firebase SDK의 버전 2.0.0에는 Firestore 트리거 함수의 타임스탬프에 대한 변경사항이 있습니다.

SDK를 최신 버전으로 업데이트하려면 함수 폴더에서 다음을 실행합니다.

npm install firebase-functions@latest --save
npm install firebase-admin@latest --save-exact

Firebase CLI 또한 최신 버전으로 업데이트해야 합니다.

npm install -g firebase-tools

HTTP가 아닌 모든 비동기 함수에 영향을 주는 SDK 변경사항

트리거 유형별 SDK 변경사항

함수 에뮬레이션 변경사항

HTTP가 아닌 모든 백그라운드 함수에 영향을 주는 SDK 변경사항

이벤트 매개변수가 data 및 context로 분할됨

Cloud Functions용 Firebase SDK의 v1.0부터 비동기 함수의 event 매개변수가 사용되지 않으며 datacontext라는 새로운 매개변수 2개로 교체되었습니다.

data 매개변수는 함수를 트리거한 데이터를 나타냅니다. data 매개변수의 필드는 트리거 유형에 따라 결정되며 유형별로 다릅니다. 예를 들어 실시간 데이터베이스의 경우 data 매개변수는 DataSnapshot입니다. data 매개변수에 대한 자세한 내용은 트리거 유형별 변경사항을 참조하세요.

context 매개변수는 함수의 실행에 대한 정보를 제공합니다. 비동기 함수 유형 전반에 걸쳐 동일하며 contexteventId, timestamp, eventType, resource, params 필드가 포함됩니다. 또한 실시간 데이터베이스 함수는 함수를 트리거한 사용자에 대한 인증 정보를 제공합니다. 실시간 데이터베이스 쓰기로 트리거되는 함수에 정의된 context 필드의 예는 다음과 같습니다.

exports.dbWrite = functions.database.ref('/path/with/{id}').onWrite((data, context) => {
  const authVar = context.auth; // Auth information for the user.
  const authType = context.authType; // Permissions level for the user.
  const pathId = context.params.id; // The ID in the Path.
  const eventId = context.eventId; // A unique event ID.
  const timestamp = context.timestamp; // The timestamp at which the event happened.
  const eventType = context.eventType; // The type of the event that triggered this function.
  const resource = context.resource; // The resource which triggered the event.
  // ...
});

firebase-admin에 대한 새로운 초기화 구문

이제 Cloud Functions 런타임 내의 매개변수 없이 firebase-admin을 초기화할 수 있습니다.

이전(v0.9.1 이하)

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

현재(v1.0.0 이상)

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

초기화할 때 더 이상 functions.config().firebase를 전달할 수 없다는 점에 유의하세요. v1.0.0에서 구성에 액세스하는 자세한 방법은 다음 섹션을 참조하세요.

functions.config().firebase 삭제됨

functions.config().firebase가 삭제되었습니다. Firebase 프로젝트에서 구성 값에 액세스하려면 process.env.FIREBASE_CONFIG를 사용하세요.

let firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG);
/* {  databaseURL: 'https://databaseName.firebaseio.com',
       storageBucket: 'projectId.appspot.com',
       projectId: 'projectId' }
*/

트리거 유형별 SDK 변경사항

지원되는 여러 함수 트리거에서 v 1.0부터 데이터 필드 및 메서드의 이름 지정이 변경되었습니다. 이 섹션에 트리거 유형별 변경사항이 나와 있습니다.

실시간 데이터베이스

이벤트 데이터가 DataSnapshot으로 변경됨

이전 출시 버전에서는 event.dataDeltaSnapshot이었으나 v 1.0부터는 DataSnapshot입니다.

onWriteonUpdate 이벤트의 경우 데이터 매개변수에 beforeafter 필드가 있습니다. 각각 DataSnapshot이며 admin.database.DataSnapshot에 있는 것과 동일한 메서드를 포함합니다. 예를 들면 다음과 같습니다.

이전(v0.9.1 이하)

exports.dbWrite = functions.database.ref('/path').onWrite((event) => {
  const beforeData = event.data.previous.val(); // data before the write
  const afterData = event.data.val(); // data after the write
});

현재(v1.0.0 이상)

exports.dbWrite = functions.database.ref('/path').onWrite((change, context) => {
  const beforeData = change.before.val(); // data before the write
  const afterData = change.after.val(); // data after the write
});

onCreate의 경우 데이터 매개변수는 방금 추가한 데이터를 나타내는 DataSnapshot입니다.

이전(v0.9.1 이하)

exports.dbCreate = functions.database.ref('/path').onCreate((event) => {
  const createdData = event.data.val(); // data that was created
});

현재(v1.0.0 이상)

exports.dbCreate = functions.database.ref('/path').onCreate((snap, context) => {
  const createdData = snap.val(); // data that was created
});

onDelete의 경우 데이터 매개변수는 방금 삭제한 데이터를 나타내는 DataSnapshot입니다.

이전(v0.9.1 이하)

exports.dbDelete = functions.database.ref('/path').onDelete((event) => {
  const deletedData = event.data.previous.val(); // data that was deleted
});

현재(v1.0.0 이상)

exports.dbDelete = functions.database.ref('/path').onDelete((snap, context) => {
  const deletedData = snap.val(); // data that was deleted
});

사용자 인증 정보의 새 속성

함수를 트리거한 사용자의 권한을 비롯하여 사용자 정보에 액세스하기 위한 새로운 속성 2개가 EventContext.auth V1.0.0에 도입되었습니다.

  • EventContext.auth. uid 및 인증된 사용자의 인증 토큰과 같은 정보가 포함됩니다.
  • EventContext.authType. 권한 수준이 포함되어 있으므로 예를 들어 사용자가 관리자인지 감지할 수 있습니다.

문서화되지 않은 event.auth 필드를 사용하는 개발자는 이러한 새 속성을 사용하도록 모든 관련 코드를 업데이트해야 합니다.

adminRefref로 교체됨

.adminRef 참조는 삭제되었으며 이제 관리자 권한으로 승인되는 .ref 참조를 사용합니다. 변경사항에 대한 참조가 변경사항을 트리거한 사용자로 승인되므로 .ref를 사용하는 이전 방식은 더 이상 지원되지 않습니다.

이전(v0.9.1 이하)

exports.dbCreate = functions.database.ref('/path/{uid}').onCreate((event) => {
  const parentRef = event.data.adminRef.parent; // The Database reference to the parent authorized with admin privileges.

  const parentRefAsUser = event.data.ref.parent; // The Database reference to the parent authorized as the user which triggered the change.
});

현재(v1.0.0 이상)

exports.dbCreate = functions.database.ref('/path/{uid}').onCreate((snap, context) => {
  const parentRef = snap.ref.parent; // The Database reference to the parent authorized with admin privileges
});

Admin SDK를 사용하면 실시간 데이터베이스에 대한 사용자 승인 변경사항을 계속 처리할 수 있습니다.

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });

Cloud Firestore

v1.0의 실시간 데이터베이스 변경사항과 마찬가지로 onWriteonUpdatebeforeafter 필드가 포함된 데이터 매개변수가 있습니다. onCreateonDelete에 대한 이벤트 모두 Cloud Firestore DocumentSnapshot인 데이터 매개변수가 있습니다.

이전(v0.9.1 이하)

exports.dbWrite = functions.firestore.document('/doc/path').onWrite((event) => {
  const beforeData = event.data.previous.data(); // data before the write
  const afterData = event.data.data(); // data after the write
});

현재(v1.0.0 이상)

exports.dbWrite = functions.firestore.document('/doc/path').onWrite((change, context) => {
  const beforeData = change.before.data(); // data before the write
  const afterData = change.after.data(); // data after the write
});

onCreateonDelete에 대한 이벤트 모두 DocumentSnapshot인 데이터 매개변수가 있습니다.

이전(v0.9.1 이하)

exports.dbDelete = functions.firestore.document('/doc/path').onDelete((event) => {
  const deletedData = event.data.previous.data(); // data that was deleted
});

현재(v1.0.0 이상)

exports.dbDelete = functions.firestore.document('/doc/path').onDelete((snap, context) => {
  const deletedData = snap.data(); // data that was deleted
});

v2.0.0의 Firebase 타임스탬프 변경사항

Cloud Functions용 Firebase SDK의 v2.0.0부터 함수 내에 수신된 Firestore 스냅샷의 타임스탬프 값은 Firestore 타임스탬프 객체입니다. 이는 snapshot.createTime, snapshot.updateTime, snapshot.readTimesnapshot.data()의 모든 타임스탬프 값에 적용됩니다.

현재(v2.0.0 이상)

exports.dbCreate = functions.firestore.document('/doc/path').onCreate((snap, context) => {
  //seconds of UTC time since Unix epoch
  console.log(snap.createTime.seconds);

  //fractions of a second at nanosecond resolution, 0 to 999,999,999
  console.log(snap.createTime.nanoseconds);
});

인증

이전 출시 버전에는 event.data.metadata에 지원 중단된 createdAtlastSignedInAt 필드가 포함되어 있습니다. 버전 1.0에서 이러한 필드가 완전히 삭제되고 userRecord.metadata 매개변수의 creationTimelastSignInTime 필드로 교체됩니다.

이전(v0.9.1 이하)

// This code won't work with Cloud Functions SDK 1.0 and higher!
exports.authAction = functions.auth.user().onCreate((event) => {
  const userMetadata = event.data.metadata;

  const creationTime = userMetadata.createdAt; // 2016-12-15T19:37:37.059Z
  const lastSignInTime = userMetadata.lastSignedInAt; // 2018-01-03T16:23:12.051Z
}

현재(v1.0.0 이상)

exports.authAction = functions.auth.user().onCreate((userRecord, context) => {
  const creationTime = userRecord.metadata.creationTime; // 2016-12-15T19:37:37.059Z
  const lastSignInTime = userRecord.metadata.lastSignInTime; // 2018-01-03T16:23:12.051Z
}

Crashlytics

v1.0에서 새 문제가 발생할 때마다 실행되는 이벤트 핸들러는 onNew입니다. onNewDetected라는 이전 핸들러가 삭제되었습니다.

이전(v0.9.1 이하)

exports.newIssue = functions.crashlytics.issue().onNewDetected((event) => {
  const issue = event.data;

  const issueId = issue.issueId;
  const issueTitle = issue.issueTitle;
  const appName = issue.appInfo.appName;
  const appId = issue.appInfo.appId;
  const appPlatform = issue.appInfo.appPlatform;
  const latestAppVersion = issue.appInfo.latestAppVersion;
  const createTime = issue.createTime;
}

현재(v1.0.0 이상)

exports.newIssue = functions.crashlytics.issue().onNew((issue, context) => {
  const issueId = issue.issueId;
  const issueTitle = issue.issueTitle;
  const appName = issue.appInfo.appName;
  const appId = issue.appInfo.appId;
  const appPlatform = issue.appInfo.appPlatform;
  const latestAppVersion = issue.appInfo.latestAppVersion;
  const createTime = issue.createTime;
}

저장소

onChange 이벤트 핸들러가 삭제되었습니다. 그 대신 v1.0에서 다음 이벤트를 지원합니다.

  • onArchive: 버킷에서 객체 버전 관리를 사용 설정한 경우에만 전송됩니다. 이 이벤트는 객체의 서비스 중인 버전을 보관처리했었거나 이름이 동일한 객체를 업로드하여 덮어썼으므로 서비스 중인 버전이 보관처리된 버전이 되었음을 나타냅니다.
  • onDelete: 객체가 영구적으로 삭제되면 전송됩니다. 여기에는 덮어썼거나 버킷 수명 주기 구성에 따라 삭제된 객체가 포함됩니다. 객체 버전 관리를 사용 설정한 버킷에서는 객체를 보관처리(onArchive 참조)하면 storage.objects.delete 메서드를 통해 보관처리했더라도 이 이벤트가 전송되지 않습니다.
  • onFinalize: 버킷에서 새 객체나 기존 객체의 새 세대를 만들면 전송됩니다. 여기에는 기존 객체의 복사나 재작성이 포함됩니다. 실패한 업로드는 이 이벤트를 트리거하지 않습니다.
  • onMetadataUpdate: 기존 객체의 메타데이터가 변경되면 전송됩니다.

이전(v0.9.1 이하)

exports.processFile = functions.storage.object().onChange((event) => {
  const object = event.data;

  const filePath = object.name; // Path of the File
  const contentType = object.contentType; // Mime type of the file

  // Exit if this is a deletion event.
  if (object.resourceState === 'not_exists') {
    console.log('This file was deleted.');
    return null;
  }

  // Exit if file exists but is not new and is only being triggered
  // because of a metadata change.
  if (resourceState === 'exists' && metageneration > 1) {
    console.log('This is a metadata change event.');
    return null;
  }

  // ...
}

현재(v1.0.0 이상)

exports.processFile = functions.storage.object().onFinalize((object, context) => {
  const filePath = object.name; // Path of the File
  const contentType = object.contentType; // Mime type of the file

  // ...
}

exports.fileDeleted = functions.storage.object().onDelete((object, context) => {
  console.log('This file was deleted.');
}

exports.metadataUpdated = functions.storage.object().onMetadataUpdate((object, context) => {
  console.log('This is a metadata change event.');
}

게시/구독

기본 트리거 유형이 변경되었으므로 게시/구독 함수의 이름을 변경해 다시 배포해야 합니다. 함수 코드는 변경하지 않아도 됩니다.

게시/구독 함수를 업데이트하는 방법은 다음 안내를 따르세요.

  1. 함수 이름을 바꿉니다. 예를 들어 'myPubSubFunction'의 이름을 'myNewPubSubFunction'으로 변경합니다.
  2. 부분 배포를 사용해 이 함수만 배포합니다.

    firebase deploy --only functions:myNewPubSubFunction

  3. 'myNewPubSubFunction'을 배포한 후 모든 함수를 배포해 사용되지 않는 v.1.0.0 이전 함수를 삭제합니다.

    firebase deploy --only functions

배포 명령어가 실행되는 잠깐 사이에 중복 트리거를 수신할 수도 있습니다. 이러한 문제를 해결하고 정상적으로 작동하게 하려면 멱등 함수를 작성합니다.

자세한 내용은 API 참조를 확인하세요.

함수 에뮬레이션 변경사항

  • 이제 firebase serve가 기본적으로 HTTP 함수와 호스팅을 둘 다 제공합니다.
  • 모든 함수를 에뮬레이션하는 firebase experimental:functions:shell의 이름이 firebase functions:shell로 변경되었습니다.

함수 셸의 구문 변경사항

함수 셸을 통해 함수를 호출하는 구문이 firebase-functions v1.0.0+의 구문을 반영하도록 업데이트되었습니다.

// Inside functions shell

// To emulate database writes done by an administrative user:
myDbFunction(‘data’)

// To emulate database writes done by an authenticated user:
myDbFunction(‘data’, { auth: { uid: ‘abc’ }})

// To emulate database writes done by an unauthenticated user:
myDbFunction(‘data’, { authMode: ‘UNAUTHENTICATED’)