Memulai: menulis, menguji, dan men-deploy fungsi pertama Anda


Untuk mulai menggunakan Cloud Functions, coba pelajari tutorial ini, yang dimulai dengan berbagai tugas penyiapan yang diperlukan, kemudian dilanjutkan dengan pembuatan, pengujian, dan deployment dua fungsi terkait:

  • Fungsi "tambahkan pesan" yang mengekspos URL yang menerima nilai teks dan menuliskannya ke Cloud Firestore.
  • Fungsi "menjadikan huruf kapital" yang dipicu pada penulisan Cloud Firestore dan mengubah teks ke huruf kapital.

Berikut ini kode contoh lengkap yang berisi fungsi:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

Tentang tutorial ini

Salah satu alasan kami memilih Cloud Firestore dan fungsi JavaScript yang dipicu HTTP untuk contoh ini adalah karena pemicu latar belakang ini dapat diuji secara menyeluruh melalui Firebase Local Emulator Suite. Kumpulan alat ini juga mendukung pemicu Realtime Database, Cloud Storage, PubSub, Auth, dan HTTP callable. Jenis pemicu latar belakang lainnya seperti pemicu Remote Config dan TestLab dapat diuji secara interaktif menggunakan kumpulan alat yang tidak dijelaskan di halaman ini.

Bagian tutorial berikut ini menjelaskan langkah-langkah yang diperlukan untuk mem-build, menguji, dan men-deploy sampel.

Membuat Project Firebase

  1. Di Firebase console, klik Add project.

    • Untuk menambahkan resource Firebase ke project Google Cloud yang sudah ada, masukkan nama project-nya atau pilih dari menu dropdown.

    • Untuk membuat project baru, masukkan nama project yang diinginkan. Anda juga dapat mengedit project ID yang ditampilkan di bawah nama project.

  2. Jika diminta, tinjau dan setujui persyaratan Firebase.

  3. Klik Continue.

  4. (Opsional) Siapkan Google Analytics untuk project Anda dan optimalkan penggunaan produk-produk Firebase berikut:

    Pilih akun Google Analytics yang ada atau buat akun baru.

    Jika Anda membuat akun baru, pilih lokasi pelaporan Analytics, lalu setujui setelan berbagi data dan persyaratan Google Analytics untuk project Anda.

  5. Klik Create project (atau Add Firebase, jika Anda menggunakan project Google Cloud yang sudah ada).

Firebase menyediakan resource untuk project Firebase Anda secara otomatis. Begitu selesai, Anda akan dibawa ke halaman ringkasan untuk project Firebase Anda di Firebase console.

Menyiapkan lingkungan Anda dan Firebase CLI

Node.js

Anda akan memerlukan lingkungan Node.js untuk menulis fungsi, dan Anda akan memerlukan Firebase CLI untuk men-deploy fungsi ke runtime Cloud Functions. Untuk menginstal Node.js dan npm, sebaiknya gunakan Node Version Manager.

Setelah Node.js dan npm terinstal, instal Firebase CLI melalui metode pilihan Anda. Untuk menginstal CLI melalui npm, gunakan:

npm install -g firebase-tools

Tindakan ini akan menginstal perintah firebase yang tersedia secara global. Jika perintah gagal, Anda mungkin perlu mengubah izin npm. Untuk mengupdate ke versi terbaru firebase-tools, jalankan kembali perintah yang sama.

Python

Anda akan memerlukan lingkungan Python untuk menulis fungsi, dan Anda akan memerlukan Firebase CLI untuk men-deploy fungsi ke runtime Cloud Functions. Sebaiknya gunakan venv untuk mengisolasi dependensi. Python versi 3.10 dan 3.11 didukung.

Setelah Python terinstal, instal Firebase CLI melalui metode pilihan Anda.

Melakukan inisialisasi project

Saat melakukan inisialisasi Firebase SDK untuk Cloud Functions, buat project kosong yang berisi dependensi dan beberapa kode contoh minimal. Jika menggunakan Node.js, Anda dapat memilih TypeScript atau JavaScript untuk membuat fungsi. Untuk keperluan tutorial ini, Anda juga harus melakukan inisialisasi Cloud Firestore.

Untuk melakukan inisialisasi project Anda:

  1. Jalankan firebase login untuk login melalui browser dan mengautentikasi Firebase CLI.
  2. Buka direktori project Firebase Anda.
  3. Jalankan firebase init firestore. Untuk tutorial ini, Anda dapat menerima nilai default saat diminta untuk file indeks dan aturan Firestore. Jika belum menggunakan Cloud Firestore dalam project ini, Anda juga harus memilih mode awal dan lokasi untuk Firestore seperti yang dijelaskan di halaman Mulai menggunakan Cloud Firestore.
  4. Jalankan firebase init functions. CLI akan meminta Anda untuk memilih codebase yang sudah ada atau melakukan inisialisasi dan memberi nama baru. Saat Anda baru saja memulai, satu codebase di lokasi default sudah memadai; nantinya, saat implementasi Anda diperluas, sebaiknya atur fungsi di codebase.
  5. CLI ini memberi Anda opsi dukungan bahasa berikut:

    • JavaScript
    • TypeScript
    • Python

    Untuk tutorial ini, pilih JavaScript atau Python. Untuk menulis di TypeScript, lihat cara Menulis Fungsi dengan TypeScript.

  6. CLI ini memberi Anda opsi untuk menginstal dependensi. Anda bisa menolaknya jika ingin mengelola dependensi dengan cara lain.

Setelah perintah ini berhasil diselesaikan, struktur project Anda akan terlihat seperti ini:

Node.js

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # Main source file for your Cloud Functions code
      |
      +- node_modules/ # Directory where your dependencies (declared in
                        # package.json) are installed

Untuk Node.js, file package.json yang dibuat selama inisialisasi berisi kunci penting: "engines": {"node": "18"}. Kunci ini menentukan versi Node.js Anda untuk menulis dan men-deploy fungsi. Anda dapat memilih versi yang didukung lainnya.

Python

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

Mengimpor modul yang diperlukan dan melakukan inisialisasi aplikasi

Setelah menyelesaikan tugas penyiapan, Anda dapat membuka direktori sumber dan mulai menambahkan kode seperti yang diuraikan di bagian berikut. Untuk contoh ini, project Anda harus mengimpor modul Cloud Functions dan Admin SDK. Tambahkan baris seperti berikut ke file sumber Anda:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

Baris ini memuat modul yang diperlukan dan melakukan inisialisasi instance aplikasi admin. Dari instance ini, Anda bisa melakukan perubahan pada Cloud Firestore. Dukungan Admin SDK, seperti yang tersedia untuk FCM, Authentication, dan Firebase Realtime Database, menyediakan cara andal untuk mengintegrasikan Firebase menggunakan Cloud Functions.

Firebase CLI menginstal modul Firebase Admin SDK dan Firebase SDK untuk Cloud Functions secara otomatis saat Anda melakukan inisialisasi project. Untuk mengetahui informasi selengkapnya tentang cara menambahkan library pihak ketiga ke project Anda, lihat Menangani Dependensi.

Menambahkan fungsi "tambahkan pesan"

Untuk fungsi "tambahkan pesan", tambahkan baris berikut ke file sumber Anda:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Python

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")

Fungsi "tambahkan pesan" adalah endpoint HTTP. Setiap permintaan ke endpoint akan menghasilkan objek permintaan dan respons yang diteruskan ke pengendali permintaan untuk platform Anda (onRequest() atau on_request).

Fungsi HTTP bersifat sinkron (mirip dengan fungsi callable), sehingga Anda harus mengirim respons secepat mungkin dan menunda pekerjaan menggunakan Cloud Firestore. Fungsi HTTP "tambahkan pesan" meneruskan nilai teks ke endpoint HTTP dan memasukkannya ke dalam database di jalur /messages/:documentId/original.

Menambahkan fungsi "menjadikan huruf kapital"

Untuk fungsi "menjadikan huruf kapital", tambahkan baris berikut ke file sumber Anda:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

Fungsi "menjadikan huruf kapital" dijalankan saat terjadi penulisan ke Cloud Firestore, sehingga menentukan dokumen yang akan diproses. Untuk memperoleh performa terbaik, Anda harus sespesifik mungkin.

Tanda kurung kurawal (misalnya, {documentId}) mengurung "parameter", yaitu karakter pengganti yang mengekspos data yang sesuai dengannya dalam callback. Cloud Firestore memicu callback setiap kali pesan baru ditambahkan.

Di Node.js, fungsi yang terpicu oleh peristiwa seperti peristiwa Cloud Firestore bersifat asinkron. Fungsi callback akan menampilkan null, Objek, atau Promise. Jika tidak ditampilkan hasil apa pun, waktu fungsi akan habis, sehingga akan menghasilkan sinyal error, dan fungsi tersebut akan dicoba ulang. Baca artikel tentang Sinkronisasi, Asinkronisasi, dan Promise.

Mengemulasi eksekusi fungsi

Dengan Firebase Local Emulator Suite, Anda dapat membangun dan menguji aplikasi di mesin lokal Anda, bukan men-deploy-nya ke project Firebase. Pengujian lokal selama pengembangan sangat direkomendasikan. Salah satu keuntungan pengujian lokal adalah mengurangi risiko error coding yang dapat dikenai biaya di lingkungan produksi (misalnya, loop tak terbatas).

Untuk mengemulasi fungsi Anda:

  1. Jalankan firebase emulators:start dan periksa output untuk URL Emulator Suite UI. URL defaultnya adalah localhost:4000, tetapi mungkin dihosting di port yang berbeda di mesin Anda. Masukkan URL tersebut di browser Anda untuk membuka Emulator Suite UI.

  2. Periksa output perintah firebase emulators:start untuk URL fungsi HTTP. URL tersebut akan tampak seperti http://localhost:5001/MY_PROJECT/us-central1/addMessage, dengan pengecualian:

    1. MY_PROJECT akan diganti dengan project ID Anda.
    2. Port-nya mungkin berbeda di mesin lokal Anda.
  3. Tambahkan string kueri ?text=uppercaseme ke akhir URL fungsi. Ini akan terlihat seperti: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. Jika ingin, Anda dapat mengubah pesan "uppercaseme" menjadi pesan kustom.

  4. Buat pesan baru dengan membuka URL di tab baru pada browser Anda.

  5. Lihat efek fungsi di Emulator Suite UI:

    1. Di tab Log, Anda akan melihat log baru yang menunjukkan bahwa fungsi HTTP berhasil dijalankan:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Di tab Firestore, Anda akan melihat dokumen yang berisi pesan asli serta versi huruf kapital dari pesan tersebut (jika awalnya adalah "uppercaseme," Anda akan melihat "UPPERCASEME").

Men-deploy fungsi ke lingkungan produksi

Setelah fungsi berjalan seperti yang diinginkan di emulator, Anda dapat melanjutkan untuk men-deploy, menguji, dan menjalankannya di lingkungan produksi. Perlu diingat bahwa untuk melakukan deployment dalam produksi, project Anda harus menggunakan paket harga Blaze. Lihat harga Cloud Functions.

Untuk menyelesaikan tutorial, deploy fungsi Anda, lalu jalankan.

  1. Jalankan perintah ini untuk men-deploy fungsi Anda:

     firebase deploy --only functions
     

    Setelah Anda menjalankan perintah ini, Firebase CLI akan membuat output URL untuk setiap endpoint fungsi HTTP. Dalam terminal, Anda akan melihat baris seperti ini:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    URL ini berisi project ID Anda serta region untuk fungsi HTTP. Meskipun Anda tidak perlu mengkhawatirkannya sekarang, beberapa fungsi HTTP produksi harus menentukan lokasi untuk meminimalkan latensi jaringan.

    Jika Anda menemukan error akses, seperti "Unable to authorize access to project", coba periksa aliasing project Anda.

  2. Dengan menggunakan URL yang merupakan output CLI, tambahkan parameter kueri teks, lalu buka di browser:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    Fungsi mengeksekusi dan mengalihkan browser ke Firebase console di lokasi database tempat string teks disimpan. Peristiwa penulisan ini memicu fungsi "menjadikan huruf kapital", yang menulis string dalam huruf kapital.

Setelah menerapkan dan menjalankan fungsi, Anda dapat melihat log di Google Cloud console. Jika perlu menghapus fungsi dalam pengembangan atau produksi, gunakan Firebase CLI.

Dalam produksi, sebaiknya optimalkan performa fungsi dan kontrol biaya dengan menetapkan jumlah minimum dan maksimum instance yang akan dijalankan. Lihat Mengontrol perilaku penskalaan untuk informasi selengkapnya tentang opsi runtime ini.

Langkah berikutnya

Dalam dokumentasi ini, Anda dapat mempelajari lebih lanjut cara mengelola fungsi untuk Cloud Functionsserta cara menangani semua jenis peristiwa yang didukung oleh Cloud Functions Cloud Functions.

Untuk mempelajari Cloud Functions lebih lanjut, Anda juga dapat melakukan hal berikut: