مرجع نحو زبان Common Expression برای Data Connect

این راهنماهای مرجع، سینتکس زبان عبارات مشترک (CEL) مربوط به ایجاد عبارات برای دستورالعمل‌های @auth(expr:) و @check(expr:) را پوشش می‌دهد.

اطلاعات مرجع کامل برای CEL در مشخصات CEL ارائه شده است.

متغیرهای آزمایشی ارسال شده در پرس‌وجوها و جهش‌ها

سینتکس @auth(expr) ‎ به شما امکان دسترسی و آزمایش متغیرها از طریق کوئری‌ها و جهش‌ها را می‌دهد.

برای مثال، می‌توانید یک متغیر عملیاتی، مانند $status ، را با استفاده از vars.status اضافه کنید.

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

داده‌های موجود برای عبارات: درخواست، پاسخ، این

شما از داده‌ها برای موارد زیر استفاده می‌کنید:

  • ارزیابی با عبارات CEL در دستورالعمل‌های @auth(expr:) و @check(expr:)
  • انتساب با استفاده از عبارات سرور، <field>_expr .

هر دو عبارت CEL @auth(expr:) و @check(expr:) می‌توانند موارد زیر را ارزیابی کنند:

  • request.operationName
  • vars (نام مستعار برای request.variables )
  • auth (نام مستعار request.auth )

در جهش‌ها، می‌توانید به محتویات موارد زیر دسترسی داشته باشید و آنها را اختصاص دهید:

  • response (برای بررسی نتایج جزئی در منطق چند مرحله‌ای)

علاوه بر این، عبارات @check(expr:) می‌توانند موارد زیر را ارزیابی کنند:

  • this (مقدار فیلد فعلی)
  • response (برای بررسی نتایج جزئی در منطق چند مرحله‌ای)

اتصال request.operationName

متغیر request.operarationName نوع عملیات، چه پرس‌وجو و چه جهش، را ذخیره می‌کند.

اتصال vars (request.vars)

اتصال vars به ​​عبارات شما اجازه می‌دهد تا به تمام متغیرهای ارسالی در پرس‌وجو یا جهش شما دسترسی داشته باشند.

شما می‌توانید از vars.<variablename> در یک عبارت به عنوان یک نام مستعار برای request.variables.<variablename> با اعتبار کامل استفاده کنید:

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

اتصال auth (request.auth)

Authentication کاربرانی را که درخواست دسترسی به داده‌های شما را دارند شناسایی می‌کند و آن اطلاعات را به عنوان یک متغیر (binding) در اختیار شما قرار می‌دهد که می‌توانید در عبارات خود بر اساس آن عمل کنید.

در فیلترها و عبارات خود، می‌توانید auth به عنوان نام مستعار برای request.auth استفاده کنید.

اتصال auth شامل اطلاعات زیر است:

  • uid : یک شناسه کاربری منحصر به فرد که به کاربر درخواست کننده اختصاص داده می‌شود.
  • token : نقشه‌ای از مقادیر جمع‌آوری‌شده توسط Authentication .

برای جزئیات بیشتر در مورد محتویات auth.token به داده‌های موجود در توکن‌های auth مراجعه کنید.

اتصال response

اتصال response شامل داده‌هایی است که توسط سرور در پاسخ به یک پرس‌وجو یا جهش ، همزمان با جمع‌آوری داده‌ها، جمع‌آوری می‌شوند .

با پیشرفت عملیات، و با تکمیل موفقیت‌آمیز هر مرحله، response شامل داده‌های پاسخ از مراحل تکمیل‌شده با موفقیت است.

اتصال response بر اساس شکل عملیات مرتبط با آن، شامل (چندین) فیلد تو در تو و (در صورت وجود) پرس‌وجوهای تعبیه‌شده، ساختار یافته است.

توجه داشته باشید که وقتی به داده‌های پاسخ پرس‌وجوی جاسازی‌شده دسترسی پیدا می‌کنید، فیلدها می‌توانند شامل هر نوع داده‌ای باشند، بسته به داده‌های درخواست‌شده در پرس‌وجوی جاسازی‌شده؛ وقتی به داده‌های برگردانده‌شده توسط فیلدهای جهش مانند _insert s و _delete s دسترسی پیدا می‌کنید، ممکن است حاوی کلیدهای UUID، تعداد حذف‌ها، و مقادیر تهی باشند (به مرجع جهش‌ها مراجعه کنید).

برای مثال:

  • در یک جهش که شامل یک کوئری جاسازی‌شده است، اتصال response شامل داده‌های جستجو در response.query.<fieldName>.<fieldName>.... است، که در این مورد، response.query.todoList و response.query.todoList.priority .
mutation CheckTodoPriority(
  $uniqueListName: String!
) {
  # This query is identified as `response.query`
  query @check(expr: "response.query.todoList.priority == 'high'", message: "This list is not for high priority items!") {
    # This field is identified as `response.query.todoList`
    todoList(where: { name: $uniqueListName }) {
      # This field is identified as `response.query.todoList.priority`
      priority
    }
  }
}
  • در یک جهش چند مرحله‌ای، برای مثال با چندین فیلد _insert ، اتصال response شامل داده‌های جزئی در response.<fieldName>.<fieldName>.... ، که در این مورد، response.todoList_insert.id .
mutation CreateTodoListWithFirstItem(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Step 1
  todoList_insert(data: {
    id_expr: "uuidV4()",
    name: $listName,
  })
  # Step 2:
  todo_insert(data: {
    listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
    content: $itemContent,
  })
}

this الزام آور است

اتصال this به فیلدی که دستورالعمل @check به آن متصل است، ارزیابی می‌شود. در یک مورد اساسی، ممکن است نتایج پرس‌وجوی تک مقداری را ارزیابی کنید.

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

اگر فیلد برگردانده شده چندین بار تکرار شود، زیرا هر جد یک لیست است، هر تکرار با this پیوند به هر مقدار بررسی می‌شود.

برای هر مسیر داده شده، اگر یک جد null یا [] باشد، به آن فیلد دسترسی پیدا نمی‌شود و ارزیابی CEL برای آن مسیر نادیده گرفته می‌شود. به عبارت دیگر، ارزیابی فقط زمانی انجام می‌شود که this null یا غیر null باشد، اما هرگز undefined .

وقتی خود فیلد یک لیست یا شیء باشد، this از همان ساختار (شامل تمام فرزندان انتخاب شده در مورد اشیاء) پیروی می‌کند، همانطور که در مثال زیر نشان داده شده است.

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

نحو عبارت پیچیده

شما می‌توانید با ترکیب عملگرهای && و || عبارات پیچیده‌تری بنویسید.

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

بخش زیر تمام عملگرهای موجود را شرح می‌دهد.

عملگرها و اولویت عملگرها

از جدول زیر به عنوان مرجع برای عملگرها و اولویت مربوط به آنها استفاده کنید.

با توجه به عبارات دلخواه a و b ، یک فیلد f و یک اندیس i .

اپراتور توضیحات شرکت‌پذیری
a[i] a() af فهرست، فراخوانی، دسترسی به فیلد چپ به راست
!a -a نفی تک‌وجهی راست به چپ
a/ba%ba*b عملگرهای ضربی چپ به راست
a+b ab عملگرهای افزایشی چپ به راست
a>b a>=b a<b a<=b عملگرهای رابطه‌ای چپ به راست
a in b وجود در لیست یا نقشه چپ به راست
type(a) == t مقایسه نوع، که در آن t می‌تواند bool، int، float، number، string، list، map، timestamp یا duration باشد. چپ به راست
a==ba!=b عملگرهای مقایسه‌ای چپ به راست
a && b شرطی و چپ به راست
a || b یا شرطی چپ به راست
a ? true_value : false_value عبارت سه‌تایی چپ به راست

داده‌ها در توکن‌های احراز هویت

شیء auth.token می‌تواند شامل مقادیر زیر باشد:

میدان توضیحات
email آدرس ایمیل مرتبط با حساب، در صورت وجود.
email_verified اگر کاربر تأیید کرده باشد که به آدرس email دسترسی دارد، true برمی‌گرداند. برخی از ارائه‌دهندگان به‌طور خودکار آدرس‌های ایمیل متعلق به خود را تأیید می‌کنند.
phone_number شماره تلفن مرتبط با حساب، در صورت وجود.
name نام نمایشی کاربر، در صورت تنظیم.
sub شناسه کاربری فایربیس کاربر. این شناسه در یک پروژه منحصر به فرد است.
firebase.identities دیکشنری تمام هویت‌هایی که با حساب کاربری این کاربر مرتبط هستند. کلیدهای دیکشنری می‌توانند هر یک از موارد زیر باشند: email ، phone ، google.com ، facebook.com ، github.com ، twitter.com . مقادیر دیکشنری آرایه‌هایی از شناسه‌های منحصر به فرد برای هر ارائه‌دهنده هویت مرتبط با حساب هستند. به عنوان مثال، auth.token.firebase.identities["google.com"][0] شامل اولین شناسه کاربری گوگل مرتبط با حساب است.
firebase.sign_in_provider ارائه‌دهنده‌ی ورود به سیستم که برای دریافت این توکن استفاده شده است. می‌تواند یکی از رشته‌های زیر باشد: custom ، password ، phone ، anonymous ، google.com ، facebook.com ، github.com ، twitter.com .
firebase.tenant tenantId مرتبط با حساب، در صورت وجود. برای مثال، tenant2-m6tyz

فیلدهای اضافی در توکن‌های JWT ID

همچنین می‌توانید به فیلدهای auth.token زیر دسترسی داشته باشید:

ادعاهای توکن سفارشی
alg الگوریتم "RS256"
iss صادرکننده آدرس ایمیل حساب کاربری سرویس پروژه شما
sub موضوع آدرس ایمیل حساب کاربری سرویس پروژه شما
aud مخاطب "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat صادر شده در زمان زمان فعلی، بر حسب ثانیه از زمان آغاز یونیکس
exp زمان انقضا مدت زمانی که توکن از زمان آغاز یونیکس (UNIX epoch) منقضی می‌شود (بر حسب ثانیه). این زمان می‌تواند حداکثر ۳۶۰۰ ثانیه دیرتر از iat باشد.
توجه: این فقط زمانی را کنترل می‌کند که خود توکن سفارشی منقضی می‌شود. اما وقتی کاربری را با استفاده از signInWithCustomToken() وارد سیستم می‌کنید، او تا زمانی که جلسه‌اش نامعتبر شود یا کاربر از سیستم خارج شود، در دستگاه وارد سیستم باقی می‌ماند.
<claims> (اختیاری) ادعاهای سفارشی اختیاری که باید در توکن گنجانده شوند، که از طریق auth.token (یا request.auth.token ) در عبارات قابل دسترسی هستند. برای مثال، اگر یک ادعای سفارشی adminClaim ایجاد کنید، می‌توانید با auth.token.adminClaim به آن دسترسی پیدا کنید.