Bisclavret
Bisclavret

Reputation: 1331

Flutter & Firebase: How to populate an array and then later, return all the contents

I have been trying to get arrays working in Firebase, and I am aware that there are a lot of references and discussions about this online, and I have read through all of these and none of it works.

First off, the Firebase side. The structure containing the array and two example strings inside it:

Firebase Structure
  collection     ->    document    ->    fields
   userData         profileImages         URLs (array)
                                            : https://firebasestorage.googleapis.com/v0/b/app-138804.appspot.com/o/jRwscYWLs1DySLMz7jn5Yo2%2Fprofile%2Fimage_picker4459623138678.jpg?alt=media&token=ec1043b-0120-be3c-8e142417
                                            : https://firebasestorage.googleapis.com/v0/b/app-138804.appspot.com/o/jRwscYWLs3872yhdjn5Yo2%2Fprofile%2Fimage_picker445929873mfd38678.jpg?alt=media&token=ec3213b-0120-be9c-8e112632

The first issue I am facing is writing to this array in the database:

Firestore.instance.collection('userData').document('profileImages').updateData({
  'URLs': _uploadedFileURL,
});

Whenever I add data to this array, it just overwrites the existing data. I need to be able to keep all the existing data intact and simply add the current new line to the array.

Once this is working, I then need to be able to return all of the strings in this array without needing to know how many of them there will be.

For this part, I basically have nothing at this point. I could show some of the things I have tried based on suggestions from other articles on this, but none of it is even close to working correctly.

Upvotes: 0

Views: 892

Answers (2)

Bisclavret
Bisclavret

Reputation: 1331

Ok guys and girls I have worked this out. Part 1: appending data to an array in Firebase.

Firestore.instance.collection('userData').document('profileImages').updateDataupdateData({
  'URLs':FieldValue.arrayUnion([_uploadedFileURL]),
});

Where _uploadedFileURL is basically a string, for these purposes. Now I have read that arrayUnion, which is super groovy, is only available in Cloud Firestore, and not the Realtime Database. I use Cloud Firestore so it works for me but if you are having issues this might be why.

Now what is extra groovy about Cloud Firestore is that you can similarly remove an element from the array using:

Firestore.instance.collection('userData').document('profileImages').updateDataupdateData({
      'URLs':FieldValue.arrayRemove([_uploadedFileURL]),
    });

So how to get this data back out again. A simple way I have found to get that data and chuck it into a local array is like so:

List imageURLlist = [];

DocumentReference document = Firestore.instance.collection('userData').document('profileImages');
DocumentSnapshot snapshot = await document.get();
setState(() {
  imageURLlist = snapshot.data['URLs'];
});

From here at least you have the data, can add to it, can remove from it and this can be a platform for you to figure out what you want to do with it.

Upvotes: 1

Ahmed Khattab
Ahmed Khattab

Reputation: 2799

im assuming that _uploadedFileURL is a String, and you are updating the property URLs, that's why your data gets overwritten, because you are changing the URLs value to a single string which is _uploadedFileURL. to solve this issue, simply get the current data inside profileImages before commiting the update. like so

final DocumentSnapshot currentData = await Firestore.instance.collection('userData').document('profileImages').get();

Firestore.instance.collection('userData').document('profileImages').updateData({
  'URLs': [
      ...currentData.data['URLs'],
      _uploadedFileURL
  ],
});

and for the second part of your question, all you need is to query for the profileImages

Future<List<String>> _getProfileImages() {
   final document = Firestore.instance.collection('userData').document('profileImages').get();
   return document.data['profileImages]
}

the result of the get method will be a DocumentSnapshot, and inside the data property will access the profileImages which is a List<String>.

Upvotes: 2

Related Questions