Riferimento alla sintassi di Common Expression Language per Data Connect

Queste guide di riferimento illustrano la sintassi del Common Expression Language (CEL) pertinente alla creazione di espressioni per le direttive @auth(expr:) e @check(expr:).

Le informazioni di riferimento complete per CEL sono riportate nella specifica CEL.

Prova le variabili passate in query e mutazioni

La sintassi @auth(expr) ti consente di accedere e testare le variabili da query e mutazione.

Ad esempio, puoi includere una variabile di operazione, come $status, utilizzando vars.status.

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

Dati disponibili per le espressioni

Sia le espressioni CEL @auth(expr:) che @check(expr:) possono valutare quanto segue:

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

Inoltre, le espressioni @check(expr:) possono valutare:

  • this (il valore del campo corrente)

L'oggetto request.operationName

L'oggetto request.operarationName memorizza il tipo di operazione, query o mutazione.

Oggetto vars

L'oggetto vars consente alle espressioni di accedere a tutte le variabili passate nella query o nella mutazione.

Puoi utilizzare vars.<variablename> in un'espressione come alias per il valore request.variables.<variablename> completamente qualificato:

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

Oggetto auth

Authentication identifica gli utenti che richiedono l'accesso ai tuoi dati e fornisce queste informazioni come oggetto su cui puoi basare le tue espressioni.

Nei filtri e nelle espressioni, puoi utilizzare auth come alias per request.auth.

L'oggetto auth contiene le seguenti informazioni:

  • uid: un ID utente univoco assegnato all'utente che effettua la richiesta.
  • token: una mappa dei valori raccolti da Authentication.

Per maggiori dettagli sul contenuto di auth.token, consulta Dati nei token di autenticazione

L'associazione this

L'associazione this restituisce il campo a cui è associata l'istruzione @check. In un caso di base, potresti valutare risultati della query a valore singolo.

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
  })
}

Se il campo restituito si verifica più volte perché un qualsiasi antenato è un elenco, ogni occorrenza viene testata con this associato a ciascun valore.

Per un determinato percorso, se un antenato è null o [], il campo non verrà raggiunto e la valutazione CEL verrà saltata per quel percorso. In altre parole, la valutazione avviene solo quando this è null o non null, ma mai undefined.

Quando il campo stesso è un elenco o un oggetto, this segue la stessa struttura (inclusi tutti i discendenti selezionati in caso di oggetti), come illustrato nell'esempio seguente.

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
  })
}

Sintassi delle espressioni complesse

Puoi scrivere espressioni più complesse combinandole con gli operatori && e ||.

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

La sezione seguente descrive tutti gli operatori disponibili.

Operatori e precedenza degli operatori

Utilizza la seguente tabella come riferimento per gli operatori e la relativa precedenza.

Dati espressioni arbitrarie a e b, un campo f e un indice i.

Operatore Descrizione Associatività
a[i] a() a.f Accesso a indici, chiamate e campi da sinistra a destra
!a -a Negazione unaria da destra a sinistra
a/b a%b a*b Operatori moltiplicativi da sinistra a destra
a+b a-b Operatori additivi da sinistra a destra
a>b a>=b a<b a<=b Operatori relazionali da sinistra a destra
a in b Presenza in un elenco o in una mappa da sinistra a destra
type(a) == t Confronto di tipo, dove t può essere bool, int, float, number, string, list, map, timestamp o duration da sinistra a destra
a==b a!=b Operatori di confronto da sinistra a destra
a && b E condizionale da sinistra a destra
a || b OR condizionale da sinistra a destra
a ? true_value : false_value Espressione ternaria da sinistra a destra

Dati nei token di autenticazione

L'oggetto auth.token può contenere i seguenti valori:

Campo Descrizione
email L'indirizzo email associato all'account, se presente.
email_verified true se l'utente ha verificato di avere accesso all'indirizzo email. Alcuni provider verificano automaticamente gli indirizzi email di loro proprietà.
phone_number Il numero di telefono associato all'account, se presente.
name Il nome visualizzato dell'utente, se impostato.
sub L'UID Firebase dell'utente. Deve essere univoco all'interno di un progetto.
firebase.identities Dizionario di tutte le identità associate all'account di questo utente. Le chiavi del dizionario possono essere una delle seguenti: email, phone, google.com, facebook.com, github.com, twitter.com. I valori del dizionario sono array di identificatori univoci per ogni provider di identità associato all'account. Ad esempio, auth.token.firebase.identities["google.com"][0] contiene il primo ID utente Google associato all'account.
firebase.sign_in_provider Il provider di accesso utilizzato per ottenere questo token. Può essere una delle seguenti stringhe: custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com.
firebase.tenant Il tenantId associato all'account, se presente. Ad esempio, tenant2-m6tyz

Campi aggiuntivi nei token ID JWT

Puoi anche accedere ai seguenti campi auth.token:

Richieste di token personalizzati
alg Algoritmo "RS256"
iss Emittente L'indirizzo email dell'account di servizio del progetto
sub Oggetto L'indirizzo email dell'account di servizio del progetto
aud Pubblico "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Data/ora di emissione L'ora corrente, in secondi dall'epoca UNIX
exp Scadenza La data e l'ora in cui scade il token, espressa in secondi dall'epoca UNIX. Deve essere al massimo 3600 secondi dopo il valore iat.
Nota: questo controlla solo la data di scadenza del token personalizzato stesso. Tuttavia, una volta che un utente ha eseguito l'accesso utilizzando signInWithCustomToken(), l'accesso rimarrà attivo sul dispositivo finché la sessione non viene invalidata o l'utente non si disconnette.
<claims> (facoltativo) Dichiarazioni personalizzate facoltative da includere nel token, a cui è possibile accedere tramite auth.token (o request.auth.token) nelle espressioni. Ad esempio, se crei un reclamo personalizzato adminClaim, puoi accedervi con auth.token.adminClaim.