【问题标题】:Get the index ID of an item in Firebase AngularFire获取 Firebase AngularFire 中项目的索引 ID
【发布时间】:2013-10-18 21:54:42
【问题描述】:

此处提出了类似的问题,但接受的答案并没有真正回答问题。

Using AngularFire, is it possible to to create relational-style databases? Or access the UniqueIDs?

通过 AngularFire 将嵌套项添加到 Firebase 时,每个项实际上都设置在另一个以数字编号的索引下。

因此,我需要使用以下相对 url 引用用户的产品:

users/:id/products

我的问题是,一旦我创建了一个用户(或任何相关的东西),我如何获得索引值?

// Get the users
var ref = new Firebase('https://myapp.firebaseio.com/users')
var promise = angularFire(ref, $scope, 'users', {})
promise.then(function() {
  // Can I get the ID from here somehow?
})

// Users saves a product
id = null // ???
var product = {
   name: 'new product',
   desc: 'this is a new product'
}
var ref = new Firebase('https://myapp.firebaseio.com/users/' + id + '/products')
var promise = angularFire(ref, $scope, 'products', {})
promise.then(function() {
  $scope.products.push(product)
})

更新

澄清一下,这不是关于用户身份验证的问题。我已经处理好了。对困惑感到抱歉。

当我开始在 Firebase 中“在”其他东西下制作东西时,我遇到了障碍。不管是users 还是giraffes。

如果我制作“商店”,则每个商店都有“产品”(比方说。)

我希望能够使用

检索它们
stores/{storeId}/products

但理想情况下,storeId 是从 AngularFire 创建的索引 ID(参见我附上的图片)。问题是,AngularFire 只是创建了这个 ID,而不让我知道。

如果我有一些成功的功能,比如

success: function(response) { 
  $scope.store.id = response.indexId
}

这是最有意义的,但 AngularFire 似乎并没有准备好这个非常需要的功能。请证明我错了。 :)

【问题讨论】:

  • 仅供参考,您的 angularFire() 调用的最后一个参数 {} 现在已弃用。您可以通过在启动 angularFire 之前执行 $scope.users = {} 来完成类似的事情。
  • @bennlich 我是否错误地认为无论您在angularFire 返回之前如何初始化,您总是会返回一个对象?如果是这样,您可以在docs 中的隐式angularFire 绑定上使用.push() 的建议不准确吗?我知道这有点离题,但我认为仍然相关。
  • @hiattp 为什么 .push() 会出错?
  • 好吧,JavaScript 对象没有 push 方法,只有数组。
  • @hiattp 看到这个小提琴:jsfiddle.net/4zGvz/2。如果它以对象的形式开始生命,则您将返回一个对象,如果以数组的形式开始生命,则返回一个数组。否则,它会等待查看引用中已经存在的数据类型。

标签: javascript firebase angularfire


【解决方案1】:

似乎有一种方法可以做你想做的一切。你的第一个问题是:

var promise = angularFire(ref, $scope, 'users', {})
promise.then(function() {
  // Can I get the ID from here somehow?
})

一旦 promise 返回此调用,您的 $scope.users 将成为用户对象,其键是您创建的用户的 id 值。因此要访问这些用户的 ID:

var promise = angularFire(ref, $scope, 'users')
promise.then(function() {
  for(var userId in $scope.users){
    console.log("User Id: " + userId);
  }
});

这似乎对您最终要实现的目标没有太大帮助,但至少您可以看到如何从 AngularFire 返回所有用户的 id。

由于您想在users 下创建products,我认为@bennlich 试图了解用户的ID 应该可以从其他变量中获得,例如user 对象,如果您使用的是@987654329 @。但是,只要您确实拥有 id,就有多种方法可以在该用户下创建对象。假设您拥有用户 ID,您将拥有以下参考:

var userProductRef = new Firebase('https://myapp.firebaseio.com/users/' + userId + '/products');

因此,使用 AngularFire 创建 product 的一种方法是使用 angularFireCollection 创建显式数据绑定:

$scope.userProducts = angularFireCollection(userProductRef);
// create a new product
var newProductRef = $scope.userProducts.add({name: 'new product', desc: 'this is a new product'});
console.log("New product id: " + newProductRef.name());

如果您想使用隐式数据绑定,则根本不需要直接使用 AngularFire 来创建对象,因为数据同步是“隐含的”。在这种情况下,您必须记住 AngularFire 只是 vanilla Firebase API 的扩展/增强,而不是替代品。所以你可能有这样的事情,使用 Firebase .push 方法来创建 id:

// sync $scope.userProducts with Firebase
var promise = angularFire(userProductRef, $scope, 'userProducts');
// create a new product when promise fulfilled
promise.then(function(){
  var newProductId = userProductRef.push(); // here is your id
  // this will sync to Firebase automatically because of the implied angularFire binding
  $scope.userProducts[newProductId] = {name: 'new product', desc: 'this is a new product'};
});

这些方法使用 AngularFire 来创建对象,但如前所述,我认为不要将 AngularFire 视为 Firebase API 的替代品,它只会让常见的 Angular 用例变得更加容易。根据您的视图和 CRUD 操作的结构,它可能会或可能不会使用 AngularFire 进行创建,即使它对读取/更新/等操作很有用。最后一点,虽然您可以在 Firebase 中使用 AngularFire 进行这种类型的关系数据结构化,但以后可能会遇到困难。您应该强烈考虑重组 (de-normalizing) 数据以优化 Firebase 的键/值存储设计。

【讨论】:

  • 我要在这个答案中澄清的唯一一点是,在最后一个示例中,您没有 /have/ 使用 push() 来生成 id (尽管这样做肯定不是一个坏主意所以)。此外,我不确定在上一个示例中等待承诺兑现有多重要。对此有任何想法吗?
  • 不使用自己的id或者push(),你能不能在创建新产品的同时还能取回id?我想我明白你的意思,但目标似乎是使用 Firebase 生成的 id,也许我误解了。在这种情况下,我需要等待承诺,只是因为我没有设置$scope.userProducts = {},所以在承诺履行之前它实际上是未定义的。
  • 当然,如果您预先定义并且不等待,它会更干净。我试图与 OP 的原始代码保持一致,以便看起来更熟悉。
  • 哇。感谢您非常有帮助的回复。我会试试这个并返回这篇文章。
  • 我真的只是想要一个干净的解决方案,不管它是什么。文档就像我要为每一行编写规则一样。坦率地说,阅读 Firebase 文档帮助不大。
【解决方案2】:

在新版本的 AngularFire 中,您可以像普通的 javascript 对象一样迭代 AngularFire 对象。

$scope.users = {};
angularFire(ref, $scope, 'users').then(function() {
    for (var id in $scope.users) {
        if ($scope.users.hasOwnProperty(id) {
            ...
        }
    }
});

我认为这并不是您真正想要做的,因为您会将所有用户数据加载到每个客户端。您可能应该让客户提供用户名或其他类型的 id,也许是 Firebase Simple Login

最后,你熟悉浏览器的developer tools吗?它们对于窥视您不知道如何处理的对象(例如 AngularFire)内部以了解它们的内部结构非常有用。

【讨论】:

  • 你说得对,我只是以用户为例。总的来说,我精通开发人员工具和前端,但瓶颈是让 Firebase 发回我需要的数据,而无需在前端进行大量 JSON 操作。
  • 嗯,好的。也许知道你想获取什么会有所帮助?将产品存储在用户 id 下是有意义的,您只需要用户进行身份验证,以便您有一个 id 可以获取。
  • 我还没有投票或标记它,因为我不知道它是如何执行以下操作的:(1) 创建记录(用户、产品、项目等),(2)从 AngularFire 获取在 Firebase 中创建的索引 ID。
  • 我已经在上面的更新中澄清了。谢谢,@bennlich。
  • 查看 hiattp 的回答。
【解决方案3】:

对于所有此类问题,我有最好和最快的答案!

var chru;
    var ref = new Firebase("https://myapp.firebaseio.com/users/");
    var sync = $firebase(ref);
    var users= syncSelect.$asArray();
    $scope.users= users;
    users.$loaded().then(function() {
        chru = users.length;
    });

    $scope.specificIdOnSelect = function() {
        var jj;
        for (jj = 0; jj < chru; jj++) {
            var keyer = users.$keyAt(jj);
            var rec = users.$getRecord(keyer);

            if ($scope.userSelected== rec.name) {
                alert("Unique Key of " + $scope.users+ " is " + users.$keyAt(jj));
            }
        }
    };

    $scope.allIds = function() {
        var jj;
        for (jj = 0; jj < chru; jj++) {
            var keyer = users.$keyAt(jj);
            var rec = users.$getRecord(keyer);
            alert("Unique Key of " + $scope.users+ " is " + users.$keyAt(jj));
        }
    };

试试看,如果有帮助请告诉我!!!

【讨论】:

    猜你喜欢
    • 2015-05-21
    • 2015-11-15
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多