-7

My app ask the user to rate 1-6 value every day. I store it in one document for each user, I want to create a simple chart view and display graph that present user rates on x axis.

My problem is that:

When I get the values from documents it return the values in random way, every time i open the app.

In the photos i attached below you can see the code and the array that it returns.

Code

my code

Result

result

backslash-f
  • 7,923
  • 7
  • 52
  • 80
  • 7
    First of all welcome to Stackoverflow. Please don't post images. Post text. It seems that the result of the request is a dictionary. Dictionaries are unordered. You need to apply a predicate to return something sorted or `sort` `values` to the order you need. – vadian Aug 01 '19 at 18:35
  • Post your code as code, not an image. Highlight your code in Xcode, command+c from Xcode, command+v in StackOverflow editor, highlight the code, and press command+k to format it as code. – Adrian Aug 01 '19 at 18:41
  • How is your data saved in the first place? It looks like it is saved as dictionary, which is unsorted. Can you work with a sorted type when saving? e.g. array, tuple...? Otherwise you can sort the dictionary after loading with the .sorted() method, which returns a tuple. You can check out this post for more information how this works: https://stackoverflow.com/questions/25377177/sort-dictionary-by-keys – Christopher Graf Aug 01 '19 at 18:37

2 Answers2

1

Generally speaking, Firebase / Firestore rely a lot on key: value pairs, much like one would find in a Dictionary.

Dictionaries are unordered... so this

document?.data()

contains your data but it's not ordered and will vary from read to read.

One option to guarantee order is to store the values in an array.

I don't know what your Firestore structure is but suppose we have a document with several fields that contain arrays

arrays // collection
   array_doc_0 //document
      array_0    /field
         0: 1
         1: 2
         2: 3
      array_1
         0: 4
         1: 5
         2: 6

To read those in and print them to console, here's the code. Note that the content of the arrays will always be in the correct sequence, guaranteed by their array index.

func readSomeArrays() {
    let arraysCollection = self.db.collection("arrays")
    let thisArrayDoc = arraysCollection.document("array_doc_0")
    thisArrayDoc.getDocument(completion: { documentSnapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        guard let doc = documentSnapshot?.data() else { return }

        for arrayField in doc {
            let array = arrayField.value as! [Int]
            for i in array {
                print(i)
            }
        }
    })
}

and the output

[4, 5, 6]
[1, 2, 3]

note that array_1 printed before array_0. This is because again, the documentSnapshot.data() is an unordered 'Dictionary', which we are iterating over. It wasn't clear if that ordering was important but if so, store the arrays in an array, or create your own index and sort in code.

Jay
  • 34,438
  • 18
  • 52
  • 81
0

In your example, you could use sort in the data array before reading it.
As in:

data.sort()

Sample from Apple:

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
students.sort()
print(students)
// Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"

Source: https://developer.apple.com/documentation/swift/array/1688499-sort

rmaddy
  • 314,917
  • 42
  • 532
  • 579
backslash-f
  • 7,923
  • 7
  • 52
  • 80
  • What if they don't want them sorted - they want them read in, in the order they are stored in Firebase? – Jay Aug 01 '19 at 19:37
  • In that case, you will have to rethink the architecture of your app, because as mentioned by @vadian in a comment: "It seems that the result of the request is a dictionary. Dictionaries are unordered. You need to apply a predicate to return something sorted or sort values to the order you need". – backslash-f Aug 01 '19 at 20:41
  • How do you know how the data is stored? What if it was already stored in an array (which is ordered)? My point being that the OP obviously wants the data retrieved in the sequence it was stored in, not a sorted sequence. If Monday rating was 3, Tuesday rating was 2 and Wednesday Rating was 5, and then those ratings are sorted as in your answer, they would no longer correspond to the correct day. – Jay Aug 01 '19 at 21:15
  • Oh, got you now. Yeah, that makes sense. – backslash-f Aug 02 '19 at 06:11