0

I am trying to update an element located in a Firestore array but it creates a new index for me instead of modifying the element of the desired array. For more clarity, I join you my two files and the result that this provides

Class updateDescription:

import 'package:cloud_firestore/cloud_firestore.dart';

class UpdateDescription {
  final String nomVille;
  final String nomCite;
  final String photo;
  final int index;

  CollectionReference users = FirebaseFirestore.instance.collection("city");

  UpdateDescription(this.nomVille, this.nomCite, this.index, this.photo) {
    updateUser(index, photo);
  }

  Future<void> updateUser(int index, String photo) async {
    return users
        .doc(nomVille)
        .collection("citee")
        .doc(nomCite)
        .set({
          "Description": FieldValue.arrayUnion([
            {"Photo": photo}
          ])
        }, SetOptions(merge: true))
        .then((values) => print("Description deleted"))
        .catchError(
            (error) => print("Impossible de supprimer les données : $error"));
  }
}

MAIN CLASS:

import 'dart:io';
import 'package:ampc_93/fonction/firebase_crud/update_description.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

class PageDescription extends StatefulWidget {
  final String identite;
  final String surnom;
  final String caracteristiques;
  final String role;
  final String nomVille;
  final String nomCitee;
  final int index;

  PageDescription(this.identite, this.surnom, this.caracteristiques, this.role,
      this.nomVille, this.nomCitee, this.index);

  @override
  _PageDescriptionState createState() => _PageDescriptionState();
}

class _PageDescriptionState extends State<PageDescription> {
  ImagePicker _imageFile = ImagePicker();
  File? _image;

  Future getImage(ImageSource source) async {
    final pickFile = await _imageFile.getImage(source: source);
    setState(() {
      if (pickFile != null) {
        _image = File(pickFile.path);
        print(_image);
      } else {
        print("Pas d'image selectionnée");
      }
    });
    UpdateDescription(
        widget.nomVille, widget.nomCitee, widget.index, _image.toString());
    print(widget.index);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.identite),
        actions: [
          IconButton(
              onPressed: () => getImage(ImageSource.gallery),
              icon: Icon(Icons.photo_camera))
        ],
        backgroundColor: Colors.teal,
      ),
      body: SingleChildScrollView(
          padding: EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _image == null
                  ? Text("Pas d'image selectionnée $_image")
                  : Image.file(_image!),
              SizedBox(height: 20),
              Text("Identite: ${widget.identite}", textScaleFactor: 1.5),
              SizedBox(height: 20),
              Text("Surnom: ${widget.surnom}", textScaleFactor: 1.5),
              SizedBox(height: 20),
              Text("Caracteristiques: ${widget.caracteristiques}",
                  textScaleFactor: 1.5),
              SizedBox(height: 20),
              Text("Rôle: ${widget.role}", textScaleFactor: 1.5)
            ],
          )),
    );
  }
}

RESULTS OBTAINED:

enter image description here

What I want is to update the "Photo" element of my "Description" tab [0] and not create a new "Photo" element. Thank you again for your help

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
pierrot0630
  • 45
  • 1
  • 9

1 Answers1

1

If you want to modify the array, then you have to read the document, make modification to the array and then add new array again to the database:

  Future<void> updateUser(int index, String photo) async {
    List<dynamic> list = [{"Caracteristiques":"5t","Identite":"hg","Photo": photo,"Role":"tt","Surnom":"ty"}];
    return users
        .doc(nomVille)
        .collection("citee")
        .doc(nomCite)
        .update({
          "Description": FieldValue.arrayUnion(list)
        })
        .then((values) => print("Description deleted"))
        .catchError(
            (error) => print("Impossible de supprimer les données : $error"));
  }
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • @Pierre Haddad, this does not work because if there are several maps in my table, it will delete all the maps so that only one remains – pierrot0630 Jun 23 '21 at 21:41
  • 1
    @pierrot0630 yes but this is the only way https://stackoverflow.com/a/54026098/7015400. When you read the document then you would have the full array, all you have to do is to update the specific fields then add it again – Peter Haddad Jun 23 '21 at 21:44