skip to Main Content

I am trying to assign a delivery agent to the order of products with a dropdown containing a list of delivery agents. I am trying to get documentId and merging new field value to the documentId which already exists. But as a result, I a getting a duplicate document with the same documentId containing filed values which I want to merge. kindly help me to understand what I am doing wrong.

enter image description here

full code order_view.dart

import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../services/firebase_database.dart';
import '../widgets/snack_bar.dart';
import 'client_address.dart';
import 'dashboard.dart';
import 'package:url_launcher/url_launcher.dart';

class OrderView extends StatefulWidget {
  final Map<String, dynamic> orderData;
  final List<String> deliveryAgent;

  const OrderView(
      {Key? key, required this.orderData, required this.deliveryAgent})
      : super(key: key);

  @override
  State<OrderView> createState() => _OrderViewState();
}

class _OrderViewState extends State<OrderView> {
  final FirebaseDatabase _database = FirebaseDatabase();
  int index = 0;
  num totalAmount = 0;
  Map<String, dynamic> clientData = {};

  getcountTotalAmount() async {
    for (var item in widget.orderData["orders"]) {
      totalAmount = totalAmount + (item["productPrice"] * item["amount"]);
    }
    clientData = (await _database.getClientData(widget.orderData["userId"]))!;
    setState(() {});
  }

  @override
  void initState() {
    getcountTotalAmount();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    bool _isloading = true;

    return Scaffold(
      backgroundColor: Colors.grey[200],
      appBar: AppBar(
        elevation: 4,
        title: const Text("Open Order"),
        actions: [
          TextButton(
            onPressed: () async {
              showDialog(
                  context: context,
                  builder: (context) {
                    return AlertDialog(
                      content: const Text(
                        "Are you sure you want to cancel this order?",
                        textAlign: TextAlign.center,
                      ),
                      actions: [
                        TextButton(
                            onPressed: () {
                              Navigator.pop(context);
                            },
                            child: const Text(
                              "No",
                              style:
                                  TextStyle(color: Colors.green, fontSize: 16),
                            )),
                        TextButton(
                            onPressed: () async {
                              // Navigator.pop(context);
                              showDialog(
                                  context: context,
                                  builder: (context) {
                                    return LoadingAnimationWidget.inkDrop(
                                      color: Colors.orange,
                                      size: 50,
                                    );
                                  });
                              await _database.removeOrder(
                                createTime: widget.orderData["createAt"],
                              );
                              Navigator.of(context).pop();
                              Navigator.of(context).pushAndRemoveUntil(
                                MaterialPageRoute(
                                    builder: (context) =>
                                        const AdminDashboard()),
                                ModalRoute.withName(''),
                              );

                              ScaffoldMessenger.of(context).showSnackBar(
                                snackBar(
                                    message: "Your order is removed",
                                    color: Colors.deepOrange),
                              );
                            },
                            child: const Text(
                              "Yes",
                              style: TextStyle(color: Colors.red, fontSize: 16),
                            )),
                      ],
                    );
                  });
            },
            child: const Text(
              "Cancel Order",
              style: TextStyle(
                color: Colors.red,
                fontWeight: FontWeight.w500,
                fontSize: 15,
              ),
            ),
          ),
        ],
      ),
      body: SizedBox(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: ListView(
          physics: const BouncingScrollPhysics(),
          children: [
            Container(
              color: Colors.white,
              child: ListView.separated(
                padding: const EdgeInsets.symmetric(vertical: 8),
                shrinkWrap: true,
                itemCount: widget.orderData["orders"].length,
                physics: const BouncingScrollPhysics(),
                itemBuilder: (context, index) {
                  return ListTile(
                    leading: Image.network(
                      widget.orderData["orders"][index]["productImage"],
                    ),
                    title: Text(
                      widget.orderData["orders"][index]["productTitle"],
                    ),
                    subtitle: SizedBox(
                      width: MediaQuery.of(context).size.width,
                      child: Row(
                        children: [
                          Text(
                            "₹ ${widget.orderData["orders"][index]["productPrice"]}",
                            style: const TextStyle(
                                color: Colors.green, fontSize: 12),
                          ),
                          const Text(" - "),
                          Text(
                            widget.orderData["orders"][index]["productUnit"],
                            style: const TextStyle(fontSize: 12),
                          ),
                          const Text(" x "),
                          Text(widget.orderData["orders"][index]["amount"]
                              .toString()),
                          const SizedBox(width: 5),
                          Text(
                            "Total ₹ ${widget.orderData["orders"][index]["productPrice"] * widget.orderData["orders"][index]["amount"]}",
                            style: const TextStyle(
                              color: Colors.green,
                              fontWeight: FontWeight.w600,
                              fontSize: 12,
                            ),
                          ),
                        ],
                      ),
                    ),
                  );
                },
                separatorBuilder: (BuildContext context, int index) {
                  return const Divider();
                },
              ),
            ),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
              color: Colors.white,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text('Delivery Slot'),
                      Text(
                        '${widget.orderData["deliverySlot"]}',
                        style: const TextStyle(
                            fontWeight: FontWeight.w500, fontSize: 16),
                      ),
                    ],
                  ),
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Text(
                        "Delivery charge: ₹${widget.orderData["taxes"]}",
                      ),
                      Text(
                        "Total Price: ₹${totalAmount + widget.orderData["taxes"]}",
                        style: const TextStyle(
                            fontWeight: FontWeight.w500, fontSize: 16),
                      ),
                    ],
                  )
                ],
              ),
            ),
            const SizedBox(height: 16),
            Container(
              width: MediaQuery.of(context).size.width,
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
              decoration: const BoxDecoration(
                color: Colors.white,
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    'Ordered on: ${widget.orderData["createAt"]}',
                    style: const TextStyle(
                      fontWeight: FontWeight.w600,
                      fontSize: 14,
                    ),
                  ),
                  Text(
                    'Delivery at ${widget.orderData["addressType"]}',
                  ),
                  const SizedBox(
                    height: 16,
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      SizedBox(
                        width: MediaQuery.of(context).size.width * 0.6,
                        child: Text(
                          'Address: ${widget.orderData["address"]}',
                        ),
                      ),
                      ElevatedButton(
                          onPressed: () {
                            Navigator.of(context).push(MaterialPageRoute(
                                builder: (context) => ClientAddress(
                                      lat: widget.orderData["latitude"],
                                      lag: widget.orderData["longitude"],
                                    )));
                          },
                          child: const Text('Open location'))
                    ],
                  ),
                ],
              ),
            ),
            const SizedBox(
              height: 16,
            ),
            Container(
              width: MediaQuery.of(context).size.width,
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
              color: Colors.white,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    "Client Details",
                    style: TextStyle(
                      fontWeight: FontWeight.w600,
                      fontSize: 17,
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      SizedBox(
                        child: Text(
                          clientData["username"] ?? "",
                          style: const TextStyle(
                            fontWeight: FontWeight.w500,
                            fontSize: 15,
                          ),
                        ),
                      ),
                      SizedBox(
                        child: Text(
                          clientData["contact"] ?? "",
                          style: const TextStyle(
                            fontWeight: FontWeight.w500,
                            fontSize: 15,
                          ),
                        ),
                      ),
                      ElevatedButton.icon(
                        onPressed: () async {
                          String telephoneNumber = clientData["contact"];
                          Uri telephoneUrl = Uri.parse("tel:$telephoneNumber");
                          if (await canLaunchUrl(telephoneUrl)) {
                            await launchUrl(telephoneUrl);
                          }
                        },
                        icon: const Icon(
                          Icons.call,
                        ),
                        label: const Text('Call'),
                      )
                    ],
                  ),
                ],
              ),
            ),
            const SizedBox(
              height: 16,
            ),
            Container(
                width: MediaQuery.of(context).size.width,
                color: Colors.white,
                padding: const EdgeInsets.only(bottom: 8),
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        const Text(
                          "Delivery Agent",
                          style: TextStyle(
                            fontWeight: FontWeight.w500,
                            fontSize: 16,
                          ),
                        ),
                        DropdownButton(
                          items: widget.deliveryAgent
                              .map(
                                (e) => DropdownMenuItem(
                                  value: e,
                                  child: Text(e),
                                ),
                              )
                              .toList(),
                          onChanged: (val) {
                            setState(() {
                              index =
                                  widget.deliveryAgent.indexOf(val.toString());
                            });
                          },
                          isExpanded: false,
                          hint: Text(
                            widget.deliveryAgent[index],
                            style: const TextStyle(
                              fontWeight: FontWeight.w600,
                              fontSize: 15,
                            ),
                          ),
                        ),
                      ],
                    ),
                    ElevatedButton(
                        onPressed: () async {
                          bool results;
                          results = await _database.updateDeliveryAgent(
                            orderId: widget.orderData["orderId"],
                              deliveryAgent: widget.deliveryAgent[index].toString(),
                          );
                          if (results) {
                            setState(() {
                              _isloading = true;
                            });
                            ScaffoldMessenger.of(context).showSnackBar(
                              snackBar(
                                message: "Delivery agent assigned",
                                color: Colors.green,
                              ),
                            );
                          } else {
                            ScaffoldMessenger.of(context).showSnackBar(
                              snackBar(
                                message: "Error",
                                color: Colors.red,
                              ),
                            );
                          }
                          setState(() {
                            _isloading = true;
                          });
                        },
                        child: const Text('Assign Agent')),
                  ],
                )),
          ],
        ),
      ),
    );
  }
}

firebase_database.dart

CollectionReference<Map<String, dynamic>> testorders =
  FirebaseFirestore.instance.collection('testorders');

Future<bool> updateDeliveryAgent(
      {required String orderId, required String deliveryAgent}) async {
    try {
        testorders.doc(orderId).set({
          "deliveryAgent": {
            "agentName": deliveryAgent,
            "agentContact": '',
          },
        }, SetOptions(merge: true));
      return true;
    } catch (e) {
      if (kDebugMode) {
        print("error while assigning delivery agent: $e");
      }
    }
    return false;
  }

order.dart

Container(
    width: MediaQuery.of(context).size.width,
    color: Colors.white,
    padding: const EdgeInsets.only(bottom: 8),
    child: Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            const Text(
              "Delivery Agent",
              style: TextStyle(
                fontWeight: FontWeight.w500,
                fontSize: 16,
              ),
            ),
            DropdownButton(
              items: widget.deliveryAgent
                  .map(
                    (e) => DropdownMenuItem(
                      value: e,
                      child: Text(e),
                    ),
                  )
                  .toList(),
              onChanged: (val) {
                setState(() {
                  index =
                      widget.deliveryAgent.indexOf(val.toString());
                });
              },
              isExpanded: false,
              hint: Text(
                widget.deliveryAgent[index],
                style: const TextStyle(
                  fontWeight: FontWeight.w600,
                  fontSize: 15,
                ),
              ),
            ),
          ],
        ),
        ElevatedButton(
            onPressed: () async {
              bool results;
              results = await _database.updateDeliveryAgent(
                orderId: widget.orderData["orderId"],
                  deliveryAgent: widget.deliveryAgent[index].toString(),
              );
              if (results) {
                setState(() {
                  _isloading = true;
                });
                ScaffoldMessenger.of(context).showSnackBar(
                  snackBar(
                    message: "Delivery agent assigned",
                    color: Colors.green,
                  ),
                );
              } else {
                ScaffoldMessenger.of(context).showSnackBar(
                  snackBar(
                    message: "Error",
                    color: Colors.red,
                  ),
                );
              }
              setState(() {
                _isloading = true;
              });
            },
            child: const Text('Assign Agent')),
      ],
    )),

3

Answers


  1. Chosen as BEST ANSWER

    I fixed this, the main reason was firstly when I created the document with .add() where firebase auto generate the document ID, the and later while merging data in the same document ID it was creating the duplicate document ID maybe with some whitespace in it which was not visible. But to rectify I created the data with .set() by generating the document by my own and later while merging data uses the same document ID to merge new fields in the same document ID. and finally it worked.


  2. You cannot update a document ID once it’s been defined.

    See the following answer on alternative steps you can take: https://stackoverflow.com/a/52117929/9063088

    Login or Signup to reply.
  3. There is no way you can have duplicate document IDs inside the same collection. The screenshot shows two documents sharing the same ID but for sure one of them contains one or more white spaces at the end. So there are two situations, the orderId is correct and when you call set() it adds the document with a document ID that doesn’t contains white spaces, while in the database there is already one present that contains white spaces, or vice versa. When it comes to document IDs, always call .trim() so it can remove the white spaces from the beginning and from the end.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search