4 votes

Entier unique en tant que clé dans Firebase (comportement de tableau Firebase)

Si j'insère des données dans node/a/0 dans Firebase.

le résultat traitera a comme un tableau a[0].

De la même manière, si je définis mes données dans node/a/1 le premier tableau deviendra nul

      "a" : [ null, {
        "-J-22j_Mb59l0Ws0H9xc" : {
          "name" : "chok wee ching"
        }
      } ]

Mais ce sera bon si node/a/2

      "a" : {
        "2" : {
          "-J-25xjEXUqcpsC-5LOE" : {
            "name" : "chok wee ching"
          }
        }
      }

À mon avis, Firebase traite automatiquement le simple 0 et 1 comme un tableau. Comment puis-je empêcher cela?

8voto

Michael Lehenbauer Points 4538

Firebase n'a pas de support natif pour les tableaux. Si vous stockez un tableau, il est vraiment stocké en tant que "objet" avec des entiers comme noms de clé.

Cependant, pour aider les personnes qui stockent des tableaux dans Firebase, lorsque vous appelez .val() ou utilisez l'API REST pour lire des données depuis Firebase, si les données ressemblent à un tableau, Firebase les affichera comme un tableau.

En particulier, si toutes les clés sont des entiers, et que plus de la moitié des clés entre 0 et la clé maximale de l'objet ont des valeurs non vides, alors Firebase les affichera comme un tableau. C'est cette dernière partie de l'heuristique à laquelle vous vous heurtez. Votre deuxième exemple ne définit qu'une valeur pour 2, pas pour 0 et 1, donc moins de la moitié des clés ont des valeurs, et donc Firebase les affiche comme un objet.

Vous ne pouvez pas actuellement changer ou empêcher ce comportement (même si c'est une source courante de confusion donc nous sommes susceptibles de faire quelques ajustements à l'avenir). Cependant, il est généralement très facile de traiter ce comportement une fois que vous le comprenez. Si vous avez besoin d'aide supplémentaire, peut-être pouvez-vous élargir votre question pour expliquer ce que vous devez accomplir et comment ce comportement vous empêche de le faire.

1voto

jeppeb Points 530

J'ai rencontré le même problème, mais j'ai en fait voulu avoir un tableau de clés numériques en Swift ([Int:AnyObject]). J'ai écrit cette fonction pour m'assurer d'avoir toujours un tableau (sans valeurs nulles):

func forceArray(from: Any?) -> [Int:AnyObject] {        
    var returnArray = [Int:AnyObject]()

    if let array = from as? [String:AnyObject] {
        for (key, value) in array {
            if let key = Int(key) {
                returnArray[key] = value
            }
        }
        return returnArray
    }

    if let array = from as? [AnyObject] {
        for (key, value) in array.enumerated() {
            if !(value is NSNull) {
                returnArray[key] = value
            }
        }
        return returnArray
    }

    return returnArray
}

Résultat:

["0":1, "1":2] devient: [0:1, 1:2]

{"0":1, "6":2} devient: [0:1, 6:2]

["0":1, "1": null, "2":2] devient: [0:1, 2:2]

J'espère que cela sera utile pour quelqu'un!

1voto

Ben Kax Points 96

Oui, stocker 0 et 1 comme clé posera un problème car Firebase pensera que c'est un tableau.

Ma solution simple consiste à utiliser :

String(format:"%03d", intValue)

Ainsi, la clé résultante sera "000" et "001", et pourra être convertie en entier facilement.

1voto

Isantipov Points 7964

TL;DR;

Contourner pour l'API REST : ajoutez un filtre sans signification comme ceci orderBy="$.key"&startAt="0" qui filtre en réalité tous les éléments avec une clé négative) : https://workaround-arrays-bagohack.firebaseio.com/matchesHeuristic.json?orderBy=%22$key%22&startAt=%220%22&print=pretty

Explication

Il s'agit d'un comportement connu et malheureux (à mon avis) de Firebase, documenté en profondeur dans leur base de connaissances de support. Citation de Bonnes pratiques : Tableaux dans Firebase :

Firebase ne prend pas en charge nativement les tableaux. Si vous stockez un tableau, il est réellement stocké en tant qu'"objet" avec des entiers comme noms de clé.

// nous envoyons ceci ['hello', 'world'] // Firebase stocke ceci {0:'hello', 1: 'world'}

Cependant, pour aider les personnes qui stockent des tableaux dans Firebase, lorsque vous appelez .val() ou utilisez l'API REST pour lire des données, si les données ressemblent à un tableau, Firebase les affichera comme un tableau.

En particulier, *si toutes les clés sont des entiers, et que plus de la moitié des clés entre 0 et la clé maximale de l'objet ont des valeurs non vides, alors Firebase les affichera comme un tableau. Cette dernière partie est importante à garder à l'esprit.

Vous ne pouvez actuellement pas modifier ou prévenir ce comportement. En comprenant il sera plus facile de voir ce que l'on peut et ne peut pas faire lors du stockage de données semblables à un tableau.

J'ai donc créé une petite reproduction pour vous. Données originales :

{
  "matchesHeuristic": {
      "1": {
          "id": "foo",
          "value": "bar"
      },
      "2": {
          "id": "w",
          "value": "tf"
      }
  },
  "notMatchesHeuristic": {
      "1": {
          "id": "foo",
          "value": "bar"
      },
      "365": {
          "id": "w",
          "value": "tf"
      }
  }
}

Comme retourné par Firebase REST API : https://workaround-arrays-bagohack.firebaseio.com/.json?print=pretty

{
  "matchesHeuristic" : [ null, {
    "id" : "foo",
    "value" : "bar"
  }, {
    "id" : "w",
    "value" : "tf"
  } ],
  "notMatchesHeuristic" : {
    "1" : {
      "id" : "foo",
      "value" : "bar"
    },
    "365" : {
      "id" : "w",
      "value" : "tf"
    }
  }
}

comme vous pouvez le voir l'objet matchesHeuristic est transformé en un tableau avec une valeur nulle à l'index 0 (car il correspond à l'heuristique définie dans la documentation de Firebase) alors que notMatchesHeuristic est laissé intact. C'est particulièrement "agréable" si vous avez des données dynamiques comme nous - donc nous ne savons pas avant l'exécution si cela correspondra à l'heuristique ou non.

Contournement (API REST)

Cependant cette partie de la documentation ne semble pas tenir :

Vous ne pouvez actuellement pas modifier ou prévenir ce comportement. En comprenant il sera plus facile de voir ce que l'on peut et ne peut pas faire lors du stockage de données semblables à un tableau.

En réalité, vous pouvez contourner cela en demandant des éléments recherchés par clé, donc

{"1":{"id":"foo","value":"bar"},"2":{"id":"w","value":"tf"}}

NB: curieusement, il semble que les gars du support Firebase ne connaissent pas ce contournement (du moins ils ne l'ont pas suggéré lorsque nous leur avons demandé à propos de ce comportement).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X