Home > OS >  How i set the data and update the data using array of objects in Flutter/Firebase?
How i set the data and update the data using array of objects in Flutter/Firebase?

Time:02-22

I have being trying to update the data from/to Firebase, but i have some issue, and when i update the data, in the firestore, the fields are being set in null value. How can i fix?

he error is just ocorring in the Armas object, the rest data in AtributteData is fine.

MODEL

class AtributeData {
  final List<int> atributtes;
  final List<int> perks;
  final List<int> customPerksValue;
  final List<String> customPerksName;
  final List<Armas> armas;

  AtributeData(
      {this.atributtes,
      this.perks,
      this.customPerksName,
      this.customPerksValue,
      this.armas});
}

class Armas {
  final String modelo;
  final int numero;
  final int preco;

  Armas({this.modelo, this.numero, this.preco});
}

SCREEN WHEN I MAP THE DATA AND FUNCTION TO UPDATE DA DATA

class AtributteDataService {
  final String uid;
  AtributteDataService({this.uid});

  //Referencia para uma Coleção específica
  final CollectionReference atributteSheet =
      FirebaseFirestore.instance.collection('atributteSheet');

  Future updateAtributteData(
      {List<int> atributtes,
      List<int> perks,
      List<int> customPerksValue,
      List<String> customPerksName,
      List<Armas> armas,
      String modelo,
      int numero,
      int preco}) async {
    return await atributteSheet.doc(uid).set({
      'atributtes': atributtes,
      'perks': perks,
      'customPerksValue': customPerksValue,
      'customPerksName': customPerksName,
      'armas': [
        {
          'modelo': modelo,
          'numero': numero,
          'preco': preco,
        }
      ]
    });
  }

  // retorna um snapshot, mas mapeado para AtributteData
  AtributeData _atributteDataFromSnapshot(DocumentSnapshot snapshot) {
    return AtributeData(
        atributtes: List.from(snapshot['atributtes']),
        perks: List.from(snapshot['perks']),
        customPerksValue: List.from(snapshot['customPerksValue']),
        customPerksName: List.from(snapshot['customPerksName']),
        armas: List<Armas>.from(snapshot['armas'].map((e) {
          return new Armas(
            modelo: e["modelo"],
            numero: e["numero"],
            preco: e["preco"],
          );
        }))

        // markValue: List.from(snapshot['markValue']),
        );
  }

  //lista de todas as fichas dos usuários retornando em Stream

  //Obter Streams do Usuário (sem ser habilidades)
  Stream<AtributeData> get atributteData {
    return atributteSheet.doc(uid).snapshots().map(_atributteDataFromSnapshot);
  }
}

TRY TO FILL THE DATA

  await AtributteDataService(uid: user.uid).updateAtributteData(
    armas: [
      Armas(modelo: 'G2', numero: 3, preco: 3200),
      Armas(modelo: 'M4A1', numero: 1, preco: 6400),
      Armas(modelo: 'AK-47', numero: 5, preco: 7500),
    ],
    customPerksName: [],
    customPerksValue: [],
    atributtes: [0, 0, 0, 0, 0, 0, 0, 0, 0],
    perks: [
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
      0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
],

);

FIREBASE IMAGE: FIELDS FILLED BY NULL

CodePudding user response:

You're using .set() without explicitly telling it to merge existing fields with the new updates ones.

To fix it, tell Firestore to merge your new data with existing ones by passing SetOptions:

return await atributteSheet.doc(uid).set({
      'atributtes': atributtes,
      'perks': perks,
      'customPerksValue': customPerksValue,
      'customPerksName': customPerksName,
      'armas': [
        {
          'modelo': modelo,
          'numero': numero,
          'preco': preco,
        }
      ]
    }, SetOptions(merge: true));

More on this is explained in details in the FlutterFire documentation.

You need to be careful when using set as, by default, it replaces all the content of your existing record with the new one. .set() is useful in cases where you want to Crete a new document with custom ID instead of the auto-generated one by .add(), preferably, if your sole goal is to update some fields in an existing document, use .update() instead, and note that:

  1. .update() will fail if the document doesn't exist.
  2. .update() can be used if you have nested data so it gives better updating capabilities.
  • Related