Firebase - 按列过滤

Firebase - Filter by a column

我正在为我的 Angular.js 应用程序使用 Firebase。

我正在寻找相当于 SQL 的 WHERE Firebase 声明。

我在 Firebase 中存储了一系列电视剧,我只想获取具有用户输入名称的电视剧(在示例 searchQuery 中)。

Firebase 支持吗?有这样的东西吗?

var seriesRef = new Firebase('http://{app}.firebaseio.com/series');
var seriesObject = $firebaseObject(seriesRef.query({ name: searchQuery }));

我有一些建议可能对您有所帮助:

例子

  • 检查这个工作 CodePen demo
    • 我在我的 public 个 Firebase 实例中复制了您的数据。
    • 您要查找的查询是seriesCollectionRef.orderByChild('name').equalTo(seriesName)
    • 如果在输入框中输入'Avatar: The Last Airbender'并点击“查找”,您将得到匹配的系列对象。
  • 在我的示例中,我扩展了 $firebaseArray 服务以包含一种按名称查找特定系列的方法。
    • 请参阅 extending AngularFire services 的文档。
    • 您可以在不扩展服务的情况下完成同样的事情,请参阅最后一个代码片段。

工厂

app.factory('SeriesFactory', function(SeriesArrayFactory, fbUrl) {
  return function() {
    const ref = new Firebase(`${fbUrl}/series`);
    return new SeriesArrayFactory(ref);
  }
});

app.factory('SeriesArrayFactory', function($firebaseArray, $q) {
  return $firebaseArray.$extend({
    findSeries: function(seriesName) {
      const deferred = $q.defer();

      // query by 'name'
      this.$ref()
        .orderByChild('name')
        .equalTo(seriesName)
        .once('value', function(dataSnapshot) {
          if (dataSnapshot.exists()) {
            const value = dataSnapshot.val();
            deferred.resolve(value);
          } else {
            deferred.reject('Not found');
          }
        })

      return deferred.promise;
    }
  });
});

控制器

app.controller('HomeController',function($scope, SeriesFactory, fbUrl) {
  $scope.seriesName = '';

  $scope.findSeries = function() {
    const seriesCollection = new SeriesFactory();

    seriesCollection
      .findSeries($scope.seriesName)
      .then(function(data) {
        $scope.series = data;
      })
      .catch(function(error) {
        console.error(error);
      });
  };
});

没有延长服务

如果您不使用工厂,控制器函数如下所示:

$scope.findSeriesWithoutFactory = function() {
  const seriesRef = new Firebase(`${fbUrl}/series`);
  const seriesCollection = $firebaseArray(seriesRef);

  seriesCollection.$ref()
    .orderByChild('name')
    .equalTo($scope.seriesName)
    .once('value', function(dataSnapshot) {
      if (dataSnapshot.exists()){
        $scope.series = dataSnapshot.val();
      } else {
        console.error('Not found.');
      }
    });
};

规则

注意: 请务必注意,您应该将 ".indexOn": "name" 添加到您的 Firebase 规则中,以便查询高效运行。有关详细信息,请参阅 Indexing Your Data portion of the Firebase Security & Rules Guide。下面是一个例子:

"yourfirebaseapp": {
  ".read": "...",
  ".write": "...",
  "series": {
    ".indexOn": "name"
  }
}