Referensi sintaksis Common Expression Language untuk Data Connect

Panduan referensi ini membahas sintaksis Common Expression Language (CEL) yang relevan dengan pembuatan ekspresi untuk perintah @auth(expr:) dan @check(expr:).

Informasi referensi lengkap untuk CEL disediakan dalam spesifikasi CEL.

Menguji variabel yang diteruskan dalam kueri dan mutasi

Sintaksis @auth(expr) memungkinkan Anda mengakses dan menguji variabel dari kueri dan mutasi.

Misalnya, Anda dapat menyertakan variabel operasi, seperti $status, menggunakan vars.status.

mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")

Data yang tersedia untuk ekspresi

Ekspresi CEL @auth(expr:) dan @check(expr:) dapat mengevaluasi hal berikut:

  • request.operationName
  • vars (alias untuk request.variables)
  • auth (alias untuk request.auth)

Selain itu, ekspresi @check(expr:) dapat mengevaluasi:

  • this (nilai kolom saat ini)

Objek request.operationName

Objek request.operarationName menyimpan jenis operasi, baik kueri maupun mutasi.

Objek vars

Objek vars memungkinkan ekspresi Anda mengakses semua variabel yang diteruskan dalam kueri atau mutasi.

Anda dapat menggunakan vars.<variablename> dalam ekspresi sebagai alias untuk request.variables.<variablename> yang sepenuhnya memenuhi syarat:

# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")

Objek auth

Authentication mengidentifikasi pengguna yang meminta akses ke data Anda dan memberikan informasi tersebut sebagai objek yang dapat Anda buat dalam ekspresi.

Dalam filter dan ekspresi, Anda dapat menggunakan auth sebagai alias untuk request.auth.

Objek auth berisi informasi berikut:

  • uid: ID pengguna unik, yang ditetapkan untuk pengguna yang meminta.
  • token: Peta nilai yang dikumpulkan oleh Authentication.

Untuk mengetahui detail selengkapnya tentang konten auth.token, lihat Data dalam token autentikasi

Binding this

this pengikatan dievaluasi ke kolom tempat perintah @check disertakan. Dalam kasus dasar, Anda dapat mengevaluasi hasil kueri bernilai tunggal.

mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query @redact {
    moviePermission( # Look up a join table called MoviePermission with a compound key.
      key: {movieId: $movieId, userId_expr: "auth.uid"}
    ) {
      # Check if the user has the editor role for the movie. `this` is the string value of `role`.
      # If the parent moviePermission is null, the @check will also fail automatically.
      role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Jika kolom yang ditampilkan muncul beberapa kali karena setiap ancestor adalah daftar, setiap kejadian akan diuji dengan this yang terikat ke setiap nilai.

Untuk jalur tertentu, jika ancestor adalah null atau [], kolom tidak akan dijangkau dan evaluasi CEL akan dilewati untuk jalur tersebut. Dengan kata lain, evaluasi hanya terjadi jika this adalah null atau non-null, tetapi tidak pernah undefined.

Jika kolom itu sendiri adalah daftar atau objek, this akan mengikuti struktur yang sama (termasuk semua turunan yang dipilih jika berupa objek), seperti yang diilustrasikan dalam contoh berikut.

mutation UpdateMovieTitle2($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query {
    moviePermissions( # Now we query for a list of all matching MoviePermissions.
      where: {movieId: {eq: $movieId}, userId: {eq_expr: "auth.uid"}}
    # This time we execute the @check on the list, so `this` is the list of objects.
    # We can use the `.exists` macro to check if there is at least one matching entry.
    ) @check(expr: "this.exists(p, p.role == 'editor')", message: "You must be an editor of this movie to update title") {
      role
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Sintaksis ekspresi kompleks

Anda dapat menulis ekspresi yang lebih kompleks dengan menggabungkannya dengan operator && dan ||.

mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")

Bagian berikut menjelaskan semua operator yang tersedia.

Operator dan prioritas operator

Gunakan tabel berikut sebagai referensi untuk operator dan prioritasnya yang sesuai.

Ekspresi arbitrer tertentu a dan b, kolom f, dan indeks i.

Operator Deskripsi Asosiativitas
a[i] a() a.f Akses indeks, panggilan, kolom kiri ke kanan
!a -a Negasi unary kanan ke kiri
a/b a%b a*b Operator multiplikatif kiri ke kanan
a+b a-b Operator aditif kiri ke kanan
a>b a>=b a<b a<=b Operator relasional kiri ke kanan
a in b Keberadaan dalam daftar atau peta kiri ke kanan
type(a) == t Perbandingan jenis, dengan t dapat berupa bool, int, float, angka, string, daftar, peta, stempel waktu, atau durasi kiri ke kanan
a==b a!=b Operator perbandingan kiri ke kanan
a && b AND kondisional kiri ke kanan
a || b OR kondisional kiri ke kanan
a ? true_value : false_value Ekspresi ternary kiri ke kanan

Data dalam token autentikasi

Objek auth.token dapat berisi nilai berikut:

Kolom Deskripsi
email Alamat email yang terhubung dengan akun, jika ada.
email_verified true jika pengguna telah memverifikasi bahwa mereka memiliki akses ke alamat email. Beberapa penyedia secara otomatis memverifikasi alamat email yang mereka miliki.
phone_number Nomor telepon yang terkait dengan akun, jika ada.
name Nama tampilan pengguna, jika ditetapkan.
sub UID Firebase pengguna. UID ini bersifat unik dalam sebuah project.
firebase.identities Kamus yang memuat semua identitas terkait akun pengguna ini. Kunci kamus dapat berupa salah satu dari berikut ini: email, phone, google.com, facebook.com, github.com, twitter.com. Nilai kamus adalah array ID unik untuk setiap penyedia identitas yang terkait dengan akun. Misalnya, auth.token.firebase.identities["google.com"][0] berisi ID pengguna Google pertama yang dikaitkan dengan akun.
firebase.sign_in_provider Penyedia login yang digunakan untuk mendapatkan token ini. Dapat berupa salah satu string berikut: custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com.
firebase.tenant tenantId yang terkait dengan akun, jika ada. Contoh, tenant2-m6tyz

Kolom tambahan di token ID JWT

Anda juga dapat mengakses kolom auth.token berikut:

Klaim Token Kustom
alg Algoritme "RS256"
iss Penerbit Alamat email akun layanan project Anda
sub Subjek Alamat email akun layanan project Anda
aud Audience "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Waktu penerbitan Waktu saat ini, dalam satuan detik sejak epoch UNIX
exp Waktu habis masa berlaku Waktu saat token sudah tidak berlaku lagi, dalam satuan detik sejak epoch UNIX. Waktu ini bisa mencapai maksimum 3600 detik lebih lama daripada iat.
Catatan: ini hanya mengontrol kapan token kustom berhenti berlaku. Namun, setelah Anda memproses login menggunakan signInWithCustomToken(), pengguna akan tetap login di perangkatnya hingga validitas sesi berakhir atau pengguna tersebut logout.
<claims> (opsional) Klaim kustom opsional yang akan disertakan dalam token, yang dapat diakses melalui auth.token (atau request.auth.token) dalam ekspresi. Misalnya, jika Anda membuat adminClaim klaim kustom, Anda dapat mengaksesnya dengan auth.token.adminClaim.