Je construis une application très similaire à un système de gestion des stocks. Mon roadblock en ce moment est le nombre de requêtes autorisées dans Firestore, car il n'autorise pas plusieurs .where ().

Ainsi, en utilisant le concept de système de gestion des stocks, nous créons une collection:

Nous l'appellerons "InventoryCollection" . Disons qu'il a 3 champs:

- ItemID
- ItemName
- DateAdded

Chaque document de 'InventoryCollection' possède une sous-collection appelée 'PurchaseHistory' : Il a des champs:

- PurchaseID (auto generated document id)
- ItemID (from parent collection document)
- PurchaseDate
- Quantity

Dilemme: Comment déduire la quantité d'un article en utilisant le concept du premier entré, premier sorti? Supposons que Item1 ait des données 4 PurchseHistory. et disons que l'un d'eux a 0 quantité car ils ont déjà été vendus.

- PurchaseID: 12340 
- ItemID: 00001
- PurchaseDate: 01-feb-2021
- Quantity: 0

- PurchaseID: 12341(auto generated document id)
- ItemID: 00001
- PurchaseDate: 02-feb-2021
- Quantity: 10

- PurchaseID: 12342
- ItemID: 00001
- PurchaseDate: 03-feb-2021
- Quantity: 5

- PurchaseID: 12343
- ItemID: 00001
- PurchaseDate: 03-feb-2021
- Quantity: 15

Je dois trouver un moyen de récupérer le PurchaseId 12341 pour obtenir le "First In" en utilisant les paramètres ci-dessous. Je peux alors trouver un moyen de faire le "premier sorti" par moi-même:

  • obtenir tous les documents PurchaseHistory avec le ItemID: 00001
  • obtenir uniquement les documents qui ont une ou plusieurs quantités
  • trier les données par date d'achat afin que le premier résultat soit l'entrée du 2 février
  • limiter le résultat de la requête de 1 pour obtenir uniquement le document du 2 février
  • obtenez le code d'achat de ce document à utiliser dans la méthode ci-dessous:
void _deductQuantity(String itemId, String PurchaseID {
  final itemCollection = FirebaseFirestore.instance.collection('InventoryCollection').doc(ItemId).collection('PurchaseHistory').doc(purchaseID);
  itemCollection.update({
    'Quantity':  _quantity - int.parse(_editItemQuantityController.text.trim()),
  });
}

Dans mon esprit, la requête ressemble à ceci:

String purchaseIdStream;


   final docRef = FirebaseFirestore.instance.collection('InventoryCollection').doc(ItemId).collection('PurchaseHistory').doc();
    
    purchaseIdStream = await docRef
        .where('ItemId', isEqualTo: ItemId)
        .where('Quantity', isGreaterThan: 0)
        .orderBy('PurchaseDate')
        .get();
     var _id = purchaseIdStream.ref.documentID;

Je comprends parfaitement que Firebase ne permet pas de commander par, si vous n'avez pas le champ dans un .where pour acheté. Il n'est donc certainement pas possible de le faire sur le code ci-dessus. puisque j'ai déjà 2 où et un 3 où ce n'est pas possible.

Je comprends que je dois faire un filtrage côté serveur au lieu de plusieurs .where cependant, je ne suis qu'un développeur frontend. Ma compréhension des concepts backend est très limitée. J'ai donc besoin de conseils terribles sur la façon de mettre en œuvre cela dans Dart / Flutter.

Tout conseil sera très apprécié. Merci!

3
Michael Banawa 20 févr. 2021 à 16:24

3 réponses

Meilleure réponse

La réponse est d'utiliser where pour itemId et Quantity, puis effectuez le reste des filtres dans Dart:

var listOfDocs = await docRef
    .where('ItemId', isEqualTo: ItemId)
    .where('Quantity', isGreaterThan: 0)
    .get();

docs.sort((prev, next) => (prev.data()['PurchaseDate'] as Timestamp)
    .compareTo(next.data()['PurchaseDate'] as Timestamp));

final desiredDocId = docs.first.id;

print(desiredDocId);
0
Michael Banawa 13 mars 2021 à 00:29

Tout d'abord, l'attribut .where() est uniquement pour CollectionReference, pas pour DocumentReference. Supprimez le .doc(ItemId) dans docRef. Je pense que ça devrait marcher après ça.

Si ce n'est pas le cas, récupérez les données et triez-les manuellement, comme ceci:

final purchaseIdList =
    await docRef.where('ItemId', isEqualTo: ItemId).where('Quantity', isGreaterThan: 0).get();
purchaseIdList.docs.sort((QueryDocumentSnapshot a, QueryDocumentSnapshot b) =>
    (a.data()['PurchaseHistory']['PurchaseDate'] as String)
        .compareTo(b.data()['PurchaseHistory']['PurchaseDate'] as String));
final fifoId = purchaseIdList.docs[0].get('PurchaseId');

Si je manque quelque chose, dites-le. Je modifierai la réponse.

2
rkdupr0n 25 févr. 2021 à 04:29

La documentation indique que si un champ est utilisé dans orderBy, il doit également être utilisé dans le premier where.

citiesRef.where("population", ">", 100000).orderBy("population").limit(2);
0
Frank Moreno 21 févr. 2021 à 13:48