0

How do I update a field in a collection with image url? I can update with other strings but the image url doesn't seem to work. I first upload this image imageUrl in a different subcollection called "Documents". It works. I want to use the same imageUrl to UPDATE it's parent collection called 'users' with the field 'Document'. but it doesn't work. Any help?

File? image;
  String? imageUrl = "";
  String uid = FirebaseAuth.instance.currentUser!.uid;
  Future<File> customCompressed(
      {required File imagePathToCompress,
      quality = 100,
      percentage = 10}) async {
    var path = await FlutterNativeImage.compressImage(
        imagePathToCompress.absolute.path,
        quality: 100,
        percentage: 80);
    return path;
  }

  Future<File?> pickImages() async {
    File? image;
    try {
      final pickedImage =
          await ImagePicker().pickImage(source: ImageSource.camera);
      if (pickedImage != null) {
        image = File(pickedImage.path);
        File compressedImage =
            await customCompressed(imagePathToCompress: image);
        setState(() {
          image = compressedImage;
        });
      }
    } catch (e) {
      showSnackBar(context, e.toString());
    }
    return image;
  }

  upload() async {
    final authProvider = Provider.of<AuthProvider>(context, listen: false);

    String uid = FirebaseAuth.instance.currentUser!.uid;

    var imageFile = File(image!.path);

    FirebaseStorage storage = FirebaseStorage.instance;
    Reference ref = storage.ref().child("Document").child(uid);

    UploadTask uploadTask = ref.putFile(imageFile);
    await uploadTask.whenComplete(() async {
      var url = await ref.getDownloadURL();
      imageUrl = url.toString();
    }).catchError((onError) {
      return onError;
    });

    Map<String, dynamic> getdata = {
      "document": imageUrl,
      "Full name": authProvider.userModel.fullName,
      "Email": authProvider.userModel.email,
      
    };
    CollectionReference collectionReference = FirebaseFirestore.instance
        .collection('users')
        .doc(uid)
        .collection('Documants');

    collectionReference.add(getdata);
  }

  // for selecting image
  void selectImage() async {
    image = await pickImages();
  }

  CollectionReference ref = FirebaseFirestore.instance.collection('users');

TextButton(onPressed: () { upload();
ref.doc(uid).update({'Status': 'Pending verification'});
ref.doc(uid).update({'Document': imageUrl});
 },
 child: const Text('Upload document',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),))

1 Answer 1

0

To update a document, you must first create it. Then, if you want to update the value, you must perform the same action again.

Here is your code with a few modifications. The important part is that if you want to update an existing document instead of creating a new one, you need to pass an enum with the "update" operation. In the function, I retrieve the previous document ID and use the update function to modify it.

I hope it helps you. Regards. Btw, sorry if my English is not the best.

Future<void> upload({required OperationType operationType}) async {
  final authProvider = Provider.of<AuthProvider>(context, listen: false);

  final String uid = FirebaseAuth.instance.currentUser!.uid;

  final imageFile = File(image!.path);
  String? imageUrl;

  final FirebaseStorage storage = FirebaseStorage.instance;
  final Reference ref = storage.ref().child("Document").child(uid);
  final UploadTask uploadTask = ref.putFile(imageFile);
  await uploadTask.whenComplete(() async {
    final url = await ref.getDownloadURL();
    imageUrl = url;
  }).catchError((onError) {
    return onError;
  });

  final Map<String, dynamic> getdata = {
    "user_id": uid,
    "document": imageUrl,
    "full_name": authProvider.userModel.fullName,
    "email": authProvider.userModel.email,
  };
  final CollectionReference collectionReference = FirebaseFirestore.instance
      .collection('users')
      .doc(uid)
      .collection('Documants');
  if (operationType == OperationType.create) {
    await collectionReference.add(getdata);
  } else {
//Update
//Here, you need to retrieve the previously created file in order to update it.
//If you already have the value, you can pass it as an argument to the function, such as "String? docId".
    final documents = await collectionReference
        .where("user_id", isEqualTo: uid)
        .limit(1)
        .get();
    if (documents.docs.isNotEmpty) {
      final previousDocId = documents.docs[0].id;
      await collectionReference.doc(previousDocId).update(getdata);
    } else {
      // Throws Some exception because didnt find previous value
      throw Exception();
    }
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much, but here in the document side u seem to be updating the subcollection "Documents". The subcollection "Document" is a newly created subcollection after all these functions. everything works. What I wan to do is to update it's parent collection called 'users' which has a field called 'Document'.
In that case, you should do: FirebaseFirestore.instance .collection('users') .doc(uid); // This is your document reference, which has a "Document" field. And then you can simply do this: collectionReference.update(getData); It is not necessary to pass all fields in getData. You can just pass {"document": imageUrl} and it will work. Hope it helps you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.