Swift iOS rewrite a function that use Firebase database without updating a global variable
A typical way to write an asynchronous function is to have it take a function as an argument that will be called with the results when they are ready. Such a function is often called a completion handler.
private func getNumberOfRecords(category: String, completion: (Int) -&gt; Void) { 
   ...
            default: print(&quot;Error loading record from category \(category)&quot;)
            }
        }
    }
    completion(records.count)
}

Then at the call site you can write:
getNumberOfRecords(category: &quot;classical&quot;, completion: { count in ... })

or better written with trailing-closure syntax:
getNumberOfRecords(category: &quot;classical&quot;) { count in ... }

You still have the problem of three asynchronous things, and instead of chaining them together, you can also avoid looping over the data 3 times, you can loop over the data once and remember the counts for each item, using a dictionary:
private func getNumberOfRecords(completion: ([String: Int] -&gt; Void)) {
    var categoryCounts: [String: Int] = [:]

    {
    ... loop over the data here and instead of switch category ...
    categoryCounts[category] = (categoryCounts[category] ?? 0) + 1
    }

    completion(categoryCounts)
}

getNumberOfRecords { categoryCounts in 
    for (category, count) in categoryCounts {
       loadDataFromDB(records: count, category: category) 
    }
}