【问题标题】:Is it possible to do a If Else or a Switch Statement Firestore Rules是否可以执行 If Else 或 Switch 语句 Firestore 规则
【发布时间】:2019-10-13 15:10:05
【问题描述】:

是否可以在 Firestore 规则中执行 Switch 语句或 if else 语句?

我试图搜索它,但没有找到答案。

我尝试的是

function getTier() {
  return get(/users/$(request.auth.uid)).data.userTier;
}

function canAddProduct() {
  if getTier() == 'UserTier.FREE'
    // Do additional code 
    return doSomethingBasedOnFreeTier();
  else if getTier() == 'UserTier.SILVER'
    // Do additional code 
    return doSomethingBasedOnSilverTier()
  else if getTier() == 'UserTier.GOLD'
    // Do additional code 
    return doSomethingBasedOnGoldTier()
  else if getTier() == 'UserTier.COMPANY'
    // Do additional code 
    return doSomethingBasedOnCompanyTier()
}

任何帮助将不胜感激。

【问题讨论】:

  • if ... else 语句在 Firestore 的安全规则中无效。但是通常您可以通过另一个构造来完成相同的结果,例如@denniskbijo 在他们的答案中展示的基于|| 的方法。如果这对您不起作用,请确保在您的问题中包含规则的目标,因为现在它看起来像 XY problem

标签: google-cloud-firestore firebase-security


【解决方案1】:

截至 2020 年 2 月 13 日,Firestore 现在支持三元运算符

https://firebase.google.com/support/release-notes/security-rules#february_13_2020

这里是可用运算符的文档(三元在底部)

https://firebase.google.com/docs/rules/rules-language#building_conditions

从问题中获取示例代码,可以通过使用嵌套的三元运算符集来实现解决方案

function getTier() {
  return get(/users/$(request.auth.uid)).data.userTier;
}

function canAddProduct() {
  return getTier() == 'UserTier.FREE' ?
    doSomethingBasedOnFreeTier() :
    (
      getTier() == 'UserTier.SILVER' ?
        doSomethingBasedOnSilverTier() :
        (
          getTier() == 'UserTier.GOLD' ?
            doSomethingBasedOnGoldTier() :
            (
              getTier() == 'UserTier.COMPANY' ?
                doSomethingBasedOnCompanyTier() :
                null
            ) 
        )
    )
}

【讨论】:

    【解决方案2】:

    另一个需要注意的技巧是对象的使用。我花了一段时间才弄清楚这是可能的。您可以将不同的情况放入一个对象中,并使用对象键作为开关。

    function switchOnTier(tier) {
      return {
        'UserTier.FREE': doSomethingBasedOnFreeTier(),
        'UserTier.SILVER': doSomethingBasedOnSilverTier(),
        'UserTier.GOLD': doSomethingBasedOnGoldTier(),
        'UserTier.COMPANY': doSomethingBasedOnCompanyTier()
      }[tier]
    }
    

    然后你可以像这样使用它..

    return switchOnTier(getTier())
    

    我将它用于尝试将字符串复数的简单案例(这非常困难)

    function pluralize(str) {
      return {
        'AccessToken': 'AccessTokens',
        'Image': 'Images',
        'Index': 'Indexes'
      }[str]
    }
    

    希望这可以帮助其他努力解决这个问题的人。

    【讨论】:

      【解决方案3】:

      Firestore 规则旨在定义访问项目中特定集合的规则。 它们主要用于检查用户的访问权限。它们仅用于检查逻辑。所以它们不支持 switch 语句、if..else 条件和条件表达式。

      您可以使用OR条件来检查用户是否可以根据他/她所属的UserTier添加产品。

      function canAddProduct() {
          return ( getTier() == 'UserTier.FREE' || getTier() == 'UserTier.SILVER' 
                   || getTier() == 'UserTier.GOLD' || getTier() == 'UserTier.COMPANY' );
      } 
      

      这是检查访问权限的最简单方法。

      但是,对于您的特定情况,请尝试此操作。我假设您根据用户所属的层对用户进行了进一步检查。 在这里,我仅在用户属于免费层时检查用户的试用期是否已过期。

      function getUser() {
      //Get the user
          return get(/users/$(request.auth.uid)).data;
      }
      
      function canAddProduct() {
          return ( getTier() == 'UserTier.FREE' && checkFreeTierAccess(getUser()) || 
                   getTier() == 'UserTier.SILVER' && checkSilverTierAccess(getUser()) ||
                   getTier() == 'UserTier.GOLD' && checkGoldTierAccess(getUser()) ||
                   getTier() == 'UserTier.COMPANY' && checkCompanyTierAccess(getUser())
                 );
       } 
      
      function checkFreeTierAccess(user) {
      //do the checks
          return user.isTrailPeriodExpired;
      }
      

      希望这能解决您的问题。

      【讨论】:

      • 不是我想做的。我不想总是在 getTier() 上返回 true。我想要一个类似条件的 case 语句,使我能够根据 getTier() 值做更多不同的条件
      • 更新的代码或多或少反映了我想要做什么
      • @TinusJackson,唯一有效的输出值是真假,所以你想做的一切都可以归结为不同测试的 AND 和 OR。对于每个 UserTier,但它们都在括号中并将它们组合在一起,就像 Dennis 上面显示的那样 - 它做同样的事情。
      • 或者换一种说法,安全规则不允许你做'doSomething()',他们只允许你'checkSomething()',并且检查的结果最终需要是真的(允许)或 false(不允许)。
      猜你喜欢
      • 2014-06-26
      • 1970-01-01
      • 2018-11-15
      • 2015-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多