Data Connect के लिए कॉमन एक्सप्रेशन लैंग्वेज सिंटैक्स का रेफ़रंस

इस रेफ़रंस गाइड में, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) के सिंटैक्स के बारे में बताया गया है. यह सिंटैक्स, @auth(expr:) और @check(expr:) डायरेक्टिव के लिए एक्सप्रेशन बनाने से जुड़ा है.

सीईएल के बारे में पूरी जानकारी, सीईएल स्पेसिफ़िकेशन में दी गई है.

क्वेरी और म्यूटेशन में पास किए गए वैरिएबल की जांच करना

@auth(expr) सिंटैक्स की मदद से, क्वेरी और म्यूटेशन से वैरिएबल ऐक्सेस किए जा सकते हैं और उनकी जांच की जा सकती है.

उदाहरण के लिए, vars.status का इस्तेमाल करके, $status जैसे ऑपरेशन वैरिएबल को शामिल किया जा सकता है.

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

एक्सप्रेशन के लिए उपलब्ध डेटा: request, response, this

डेटा का इस्तेमाल इन कामों के लिए किया जाता है:

  • @auth(expr:) और @check(expr:) डायरेक्टिव में CEL एक्सप्रेशन का इस्तेमाल करके आकलन करना
  • सर्वर एक्सप्रेशन का इस्तेमाल करके असाइनमेंट, <field>_expr.

@auth(expr:) और @check(expr:), दोनों सीईएल एक्सप्रेशन इनका आकलन कर सकते हैं:

  • request.operationName
  • vars (request.variables के लिए उपनाम)
  • auth (request.auth के लिए उपनाम)

म्यूटेशन में, इनके कॉन्टेंट को ऐक्सेस और असाइन किया जा सकता है:

  • response (कई चरणों वाले लॉजिक में आंशिक नतीजे देखने के लिए)

इसके अलावा, @check(expr:) एक्सप्रेशन इन चीज़ों का आकलन कर सकते हैं:

  • this (मौजूदा फ़ील्ड की वैल्यू)
  • response (कई चरणों वाले लॉजिक में आंशिक नतीजे देखने के लिए)

अनुरोध का ऑपरेशन नेम बाइंडिंग

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, आपके डेटा को ऐक्सेस करने का अनुरोध करने वाले उपयोगकर्ताओं की पहचान करता है. साथ ही, यह जानकारी एक बाइंडिंग के तौर पर उपलब्ध कराता है, जिसका इस्तेमाल एक्सप्रेशन बनाने के लिए किया जा सकता है.

अपने फ़िल्टर और एक्सप्रेशन में, auth को request.auth के एलियास के तौर पर इस्तेमाल किया जा सकता है.

ऑथ बाइंडिंग में यह जानकारी शामिल होती है:

  • uid: अनुरोध करने वाले उपयोगकर्ता को असाइन किया गया यूनीक यूज़र आईडी.
  • token: Authentication से इकट्ठा की गई वैल्यू का मैप.

auth.token के कॉन्टेंट के बारे में ज़्यादा जानने के लिए, Auth टोकन में मौजूद डेटा देखें

response बाइंडिंग

response बाइंडिंग में, सर्वर से इकट्ठा किया गया डेटा होता है. यह डेटा, क्वेरी या म्यूटेशन के जवाब में इकट्ठा किया जाता है.

जैसे-जैसे कार्रवाई आगे बढ़ती है और हर चरण पूरा होता जाता है वैसे-वैसे response में, पूरे हो चुके चरणों का जवाब डेटा शामिल होता जाता है.

response बाइंडिंग को, उससे जुड़े ऑपरेशन के हिसाब से स्ट्रक्चर किया जाता है. इसमें नेस्ट किए गए (कई) फ़ील्ड और (अगर लागू हो) एम्बेड की गई क्वेरी शामिल होती हैं.

ध्यान दें कि एम्बेड की गई क्वेरी के जवाब का डेटा ऐक्सेस करते समय, फ़ील्ड में किसी भी तरह का डेटा टाइप हो सकता है. यह एम्बेड की गई क्वेरी में अनुरोध किए गए डेटा पर निर्भर करता है. म्यूटेशन फ़ील्ड, जैसे कि _insert और _delete से मिले डेटा को ऐक्सेस करते समय, उनमें यूयूआईडी कुंजियां, मिटाए गए आइटम की संख्या, और शून्य हो सकते हैं. इसके बारे में जानने के लिए, म्यूटेशन का रेफ़रंस देखें.

उदाहरण के लिए:

  • एम्बेड की गई क्वेरी वाले म्यूटेशन में, 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() a.f इंडेक्स, कॉल, फ़ील्ड ऐक्सेस बाएं से दाएं
!a -a यूनरी नेगेशन दाएं से बाएं
a/b a%b a*b गुणा करने वाले ऑपरेटर बाएं से दाएं
a+b a-b ऐडिटिव ऑपरेटर बाएं से दाएं
a>b a>=b a<b a<=b रिलेशनल ऑपरेटर बाएं से दाएं
a in b सूची या मैप में मौजूद होना बाएं से दाएं
type(a) == t टाइप की तुलना, जहां t bool, int, फ़्लोट, संख्या, स्ट्रिंग, सूची, मैप, टाइमस्टैंप या अवधि हो सकती है बाएं से दाएं
a==b a!=b कंपैरिज़न ऑपरेटर बाएं से दाएं
a && b कंडिशनल AND बाएं से दाएं
a || b कंडिशनल OR बाएं से दाएं
a ? true_value : false_value टर्नरी एक्सप्रेशन बाएं से दाएं

पुष्टि करने वाले टोकन में मौजूद डेटा

auth.token ऑब्जेक्ट में ये वैल्यू शामिल हो सकती हैं:

फ़ील्ड ब्यौरा
email अगर खाता मौजूद है, तो उससे जुड़ा ईमेल पता.
email_verified true अगर उपयोगकर्ता ने पुष्टि कर दी है कि उसके पास email पते का ऐक्सेस है. ईमेल की सेवा देने वाली कुछ कंपनियां, अपने ईमेल पतों की पुष्टि अपने-आप कर लेती हैं.
phone_number खाते से जुड़ा फ़ोन नंबर, अगर मौजूद हो.
name अगर उपयोगकर्ता का डिसप्ले नेम सेट है, तो यह उसका डिसप्ले नेम होता है.
sub उपयोगकर्ता का Firebase यूआईडी. यह किसी प्रोजेक्ट में यूनीक होता है.
firebase.identities इस उपयोगकर्ता के खाते से जुड़ी सभी पहचानों की डिक्शनरी. डिक्शनरी की कुंजियां इनमें से कोई भी हो सकती हैं: email, phone, google.com, facebook.com, github.com, twitter.com. डिक्शनरी की वैल्यू, खाते से जुड़े हर आइडेंटिटी प्रोवाइडर के लिए यूनीक आइडेंटिफ़ायर के ऐरे होते हैं. उदाहरण के लिए, auth.token.firebase.identities["google.com"][0] में खाते से जुड़ा पहला Google उपयोगकर्ता आईडी होता है.
firebase.sign_in_provider इस टोकन को पाने के लिए, साइन-इन की सुविधा देने वाली कंपनी का इस्तेमाल किया गया था. यह इनमें से कोई भी स्ट्रिंग हो सकती है: custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com.
firebase.tenant अगर खाते से जुड़ा tenantId मौजूद है, तो उसे दिखाता है. उदाहरण के लिए, tenant2-m6tyz

JWT आईडी टोकन में अतिरिक्त फ़ील्ड

इन auth.token फ़ील्ड को भी ऐक्सेस किया जा सकता है:

कस्टम टोकन के दावे
alg एल्‍गोरि‍दम "RS256"
iss जारी करने वाला आपके प्रोजेक्ट के सेवा खाते का ईमेल पता
sub विषय आपके प्रोजेक्ट के सेवा खाते का ईमेल पता
aud ऑडियंस "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat जारी करने का समय UNIX epoch के बाद से मौजूदा समय, सेकंड में
exp समाप्ति समय यह टोकन की समयसीमा खत्म होने का समय है. इसे UNIX epoch के बाद से सेकंड में दिखाया जाता है. यह iat के ज़्यादा से ज़्यादा 3600 सेकंड बाद का हो सकता है.
ध्यान दें: इससे सिर्फ़ उस समय को कंट्रोल किया जाता है जब कस्टम टोकन की समयसीमा खत्म होती है. हालांकि, signInWithCustomToken() का इस्तेमाल करके किसी उपयोगकर्ता को साइन इन कराने के बाद, वह डिवाइस में तब तक साइन इन रहेगा, जब तक उसका सेशन अमान्य नहीं हो जाता या वह साइन आउट नहीं कर लेता.
<claims> (ज़रूरी नहीं) टोकन में शामिल करने के लिए, पसंद के मुताबिक बनाए गए दावे. इन्हें एक्सप्रेशन में auth.token (या request.auth.token) के ज़रिए ऐक्सेस किया जा सकता है. उदाहरण के लिए, अगर आपने कस्टम दावा adminClaim बनाया है, तो इसे auth.token.adminClaim की मदद से ऐक्सेस किया जा सकता है.