Reputation: 379
I am instantiating a User
class via a Firebase DataSnapshot. Upon calling the initializer init(snapshot: DataSnapshot)
, I would like to asynchronously retrieve values from two distinct database references, namely pictureRef
and nameRef
, via the getFirebasePictureURL
and getFirebaseNameString
methods' @escaping completion handlers (using Firebase's observeSingleEvent
method). However, console gives me two errors: 'self' captured by a closure before all members were initialized and 'self' used in method call 'getFirebasePictureURL' before all stored properties are initialized:
import Firebase
class User {
var uid: String
var fullname: String
var pictureURL: URL
//DataSnapshot Initializer
init(snapshot: DataSnapshot) {
self.uid = snapshot.key
getFirebasePictureURL(userId: uid) { (url) in
self.getFirebaseNameString(userId: self.uid) { (fullName) in
self.fullname = fullName
self.profilePictureURL = url
}
}
func getFirebasePictureURL(userId: String, completion: @escaping (_ url: URL) -> Void) {
let currentUserId = userId
//Firebase database picture reference
let pictureRef = Database.database().reference(withPath: "pictureChildPath")
pictureRef.observeSingleEvent(of: .value, with: { snapshot in
//Picture url string
let pictureString = snapshot.value as! String
//Completion handler (escaping)
completion(URL(string: pictureString)!)
})
}
func getFirebaseNameString(userId: String, completion: @escaping (_ fullName: String) -> Void) {
let currentUserId = userId
//Firebase database name reference
let nameRef = Database.database().reference(withPath: "nameChildPath")
nameRef.observeSingleEvent(of: .value, with: { snapshot in
let fullName = snapshot.value as? String
//Completion handler (escaping)
completion(fullName!)
})
}
}
I am not too sure how I should initialize this asynchronously if this is the case.
Any help would be much appreciated!
Upvotes: 1
Views: 295
Reputation: 16456
Class can not be initialized until its all stored property initialized with default value or property should be optional or property value assigned in init
function called Designated Initializers
Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.
read this for more info. https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
So in your case you are trying fullname
and pictureURL
as stored property though your escaping closure (Async task) task which is not allowed because it is not fulfil the rule
As I mentioned earlier you have following options
Hopefully it will helpful
Upvotes: 2