简体   繁体   中英

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

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

You're using .set() without explicitly telling it to merge existing fields with the new updated 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 Create 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.

So, to add more items to an array property in Firestore, you would use .update() like this:

atributteSheet.doc(uid).update({'armas': FieldValue.arrayUnion(list)})

List items should be one of the types Firestore accepts, such as a Map or a String, so you should convert your list by mapping each item from Aramas your user-defined type, to a Map type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM