Bug in AngularFire 0.6 Causes unnecessary writes to firebase and might cause race conditions

StackOverflow https://stackoverflow.com/questions/21633857

  •  08-10-2022
  •  | 
  •  

Pregunta

I was experiencing some strange race conditions and unnecessary "set" commands being fired and started to investigate. I have not deciphered all of AngularFire's internal approach to the watch being set as a result of binding. However, there appears to be a bug with objects stored in Firebase that have a priority set on them previously.

AngularFire's watch function comparison operator will NEVER match and hence will force writes with a set. This is because the following code operates on the "local" copy:

// Parse a local model, removing all properties beginning with "$" and
// converting $priority to ".priority".
_parseObject: function(obj) {
  function _findReplacePriority(item) {
    for (var prop in item) {
      if (item.hasOwnProperty(prop)) {
        if (prop == "$priority") {
          item[".priority"] = item.$priority;
          delete item.$priority;
        } else if (typeof item[prop] == "object") {
          _findReplacePriority(item[prop]);
        }
      }
    }
    return item;
  }

This causes the angular.equals comparison to ALWAYS fail because the equality test used in the AngularFire watch function ( as a result of $bind ) is as follow:

  // We're responsible for setting up scope.$watch to reflect local changes
  // on the Firebase data.
  var unbind = scope.$watch(name, function() {
    // If the new local value matches the current remote value, we don't
    // trigger a remote update.
    var local = self._parseObject(self._parse(name)(scope));
    if (self._object.$value &&
        angular.equals(local, self._object.$value)) {
      return;
    } else if (**angular.equals(local, self._object)**) {
      return;

I have starred the problem code. This will ALWAYS evaluate to false for objects that have a pre-existing priority because the self._object will have a "$priority" and the local will have a ".priority".

I would think the code should be:

} else if (angular.equals(local,  self._parseObject(self._object))) {

I will add code that remedies this but would like the Firebase team to confirm the bug. Hard to understand that no one has encountered this. Also, not exactly clear of the purpose of univerally in AngularFire's code to convert $priority to .priority. So makes me question my analysis.

-E

¿Fue útil?

Solución

Bug confirmed and pull request done. So I will answer my own question.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top