Firebase.push failed: first argument contains an invalid key ($$hashKey)

前端 未结 6 1180
太阳男子
太阳男子 2021-02-02 13:42

I recently started learning AngularJS+Firebase. I\'m trying to write in my firebase an object like this:

{
    title: \"Personal Information\",
    say: [
               


        
相关标签:
6条回答
  • 2021-02-02 14:09

    I'm a bit late to this but I thought I would like to add my two cents as I was shaking my head to all the other answers. Hopefully this can help you to avoid this issue all together.

    Use the angularFire library intended to handle angular data and use it's methods.

    while yes you can use the pure javascript library methods to .push() .add() .update(), .set() ect.

    So if you want to avoid any clashes when firebase communicates with angular javascript you need to be using the appropriate .$foo() methods (i.e. .$save()). In your case just add the $ to your .add() (make it .$add())

    so use lessondata.$add($scope.topic);



    differences when saving with firebase's vs angularfire's


    AngularFire's $save() method is implemented using Firebase's set() method.

    Firebase's push() operation corresponds to AngularFire's $add() method

    Typically you should be using set()/$save() if you either have an object that already exists in the database or if you are working with objects that have a natural key. more info on that here: https://stackoverflow.com/a/35959496/4642530



    Things to note with AngularFire


    For a callback:

    and if you want a callback to know if your data saved correctly you can do something like this:

    var list = $firebaseArray(ref);
    list.$add({ foo: "bar" }).then(function(ref) {
      var id = ref.key();
      console.log("added record with id " + id);
      list.$indexFor(id); // returns location in the array
    });
    

    I was surprised this wasn't mentioned earlier in any of the other answers, but take a look at these docs https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray-addnewdata

    Cheers.

    0 讨论(0)
  • 2021-02-02 14:11

    The best way to get rid of the $$hasKeys is to use "track by" in ng-repeats as in the following (as mentioned in the answer above)

    <div ng-repeat="(key, value) in myObj track by $index"> ... </div>
    

    but you can also set track as par of ng-model-options

    ng-model-options="{ trackBy: '$value.someKeyOnYourObject' }"
    

    on a form control. This way also improves performance of your angular app.

    Another way is to remove the $$hashKey is using

    angular.copy(someObj);

    If all else fails, you could also use lodash to remove the keys that start with the "$".

    _.omitBy(yourObject, function(value, key){return _.startsWith(key, '$');});
    
    0 讨论(0)
  • 2021-02-02 14:14

    EDIT: As Anant points out in the comments, in the latest stable version of Angular (1.0.7 atm), you can use angular.copy(obj) to remove $$hashkey attributes.

    Like Michael said, the '$' in '$$hashKey' is the issue. Angular creates the $$hashKey properties behind the scenes (see more here: https://groups.google.com/forum/#!topic/angular/pI0IgNHKjxw). I've gotten around this issue by doing something like myRef.push(angular.fromJson(angular.toJson(myAngularObject))).

    0 讨论(0)
  • 2021-02-02 14:17

    You can also strip out the property before pushing it.

    delete $scope.topic.$$hashKey
    
    0 讨论(0)
  • 2021-02-02 14:21

    I wanted to throw another answer in here that is much simpler, just use track by in your repeat. It will get rid of the $$hashKey attribute that is causing so much grief.

    <div ng-repeat="item in items track by $index">{{item.name}}</div>
    
    0 讨论(0)
  • 2021-02-02 14:35

    The issue is the $ in "$$hashKey", not the 0. 0 is allowed.

    0 讨论(0)
提交回复
热议问题