0

I am trying to read data from Firebase Database through the .getData() as seen in my code and then adding it to an Array. When debugging the code below I can see that the assigned values in the Database can be read, however it's being appended but not saved in the array, (list : Array < String >). I am expecting seven string values in the array, but when the code is executed the array contains zero strings. I have tried hardcoding in string values to the .append but even "Bread" doesn't get saved in the end. If any further information is needed, let me know. Help would be much appreciated, thanks in beforehand!

Shows the list doesn't save the added values

Shows that the values can be read from Firebase Database and added to the list

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • 1
    Could you post your code directly into the question as text? This will make it much easier for others to answer your question. – adamjansch Jun 08 '22 at 15:54

2 Answers2

0

The problem is you're appending the values to list in the getData() completion handler, which is called asynchronously. Because of this the order of execution will be:

  1. list is defined.
  2. Requests for data will be made.
  3. awakingList is created using the empty list array.
  4. awakingList is returned with no values.
  5. getData() completion handlers are called, populating list (although I'm not sure that would actually happen, as we've already returned).

To do this correctly (and this is common with Firebase) you need to find the Firebase method that returns all your data in one go – using a for loop to retrieve data is not workable, because you make 7 separate calls via .getData(), each with its own completion handler called asynchronously. Keeping that in sync will be a nightmare.

adamjansch
  • 1,170
  • 11
  • 22
0

I see there is a completion argument in getData() which probably indicates that this function is asynchronous. That means that the function can be invoked on some other thread than the main thread and thus the code is executed in "background". And i think that happens in your code:

  1. You create empty list of strings.
  2. Then you invoke getData() function in for loop (which is asynchronous) and there you add new elements to the list.
  3. The rest of the code is synchronous (imperative) so you jump out of the loop and there is no elements in the list because the code from 2. is still executing in the background.

The most common solution to these type of situations is to force the certain piece of code to execute on main thread by putting it into:

DispatchQueue.main.async {
    ref.child("awakingTimesDate/\(i)").getData(completion: { error, snapshot in

    }
}