我有两个问题:
我知道如何使用简单的键值对向Firebase添加常规对象,但是如何添加用户对象?
在我的UserAccount对象中,我不确定UserAcct的第二个init方法。我应该使用init(snapshot:FIRDataSnapshot){}添加到Firebase还是应该坚持使用常规init方法?
我的用户模型对象:
import Foundation
import UIKit
import Firebase
import FirebaseDatabase
class UserAccount{
var userID: String
var email: String
var creationDate: String
init(userID: String, email: String, creationDate: String){
self.userID = userID
self.email = email
self.creationDate = creationDate
}//end init
//Is this second init necessary?
init(snapshot: FIRDataSnapshot) {
userID = snapshot.value!["userID"] as! String
email = snapshot.value!["email"] as! String
creationDate = snapshot.value!["creationDate"] as! String
}
}//END class
我的用户签名课程:
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
class CreateAccountController: UIViewController{
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
var dbRef: FIRDatabaseReference!
//Array to hold users
var userAcct = [UserAccount]()
override func viewDidLoad() {
super.viewDidLoad()
//Firebase Ref
self.dbRef = FIRDatabase.database().reference()
}
//Button to sign the user up
@IBAction func signUpButtonPressed(sender: UIButton) {
FIRAuth.auth()?.createUserWithEmail(emailTextField.text!, password: passwordTextField.text!, completion: {
(user, error) in
if error != nil{
print(error?.localizedDescription)
}else{
let emailAddress = self.emailTextField.text!
let currentUserID: String = (FIRAuth.auth()?.currentUser?.uid)!
let accountCreationDate = FIRServerValue.timestamp()
self.userAcct =[UserAccount(userID: currentUserID, email: emailAddress, creationDate: accountCreationDate)]
self.dbRef.child("Users").child("UserID: \(currentUserID)").child("Account-Creation-Date").setValue([\\How to add my self.userAcct model object in here? Should I add it to an array])
}
})
}
答案 0 :(得分:3)
我建议您创建一个像这样的协议:
protocol DictionaryConvertible {
init?(dict:[String:AnyObject])
var dict:[String:AnyObject] { get }
}
请注意,这是使用可选的初始化程序,这意味着它可能会失败并返回nil。我使用它来确保你需要从字典中获得的所有键值对确实存在,否则返回nil。现在,您可以像这样添加对UserAccount类的一致性:
class UserAccount: DictionaryConvertible {
var userID: String
var email: String
var creationDate: String
init(userID: String, email: String, creationDate: String){
self.userID = userID
self.email = email
self.creationDate = creationDate
}
// DictionaryConvertible protocol methods
required convenience init?(dict: [String:AnyObject]) {
guard let userID = dict["userID"] as? String, email = dict["email"] as? String, creationDate = dict["creationDate"] as? String else {
return nil
}
self.init(userID: userID, email: email, creationDate: creationDate)
}
var dict:[String:AnyObject] {
return [
"userID": userID,
"email": email,
"creationDate": creationDate
]
}
}
注意:我使用您已经创建的初始化程序来删除样板代码。要与Firebase进行互动,只需初始化您的UserAccount,如下所示:
let user:UserAccount? = UserAccount(dict: snapshot?.value as! [String:Anyobject])
要回答您的第一个问题,您可以将对象写入firebase,如下所示:
ref.child("Users").child(user!.userID).setValue(user!.dict)
你不能只将任何类型的对象写入firebase(只有NSNumber(包括BOOL),NSDictionary,NSArray,NSString,nil / NSNull来删除数据),因此你必须将你的用户对象“转换”为字典。
这种方法的优点在于它非常灵活,因此您可以简单地通过添加对协议的一致性来使用任何数据对象(尤其是在使用结构而不是类时很容易,因为这样您就可以使用扩展来添加对协议的一致性)。您甚至可以将它与任何类型的数据库一起使用,无需更改。此外,你应该确保所有这些选项都以安全的方式处理,并避免那些'!'只要有可能。
答案 1 :(得分:2)
这是我使用的方法。我在代码上面的注释中解释了所有内容。
最终结果是你创建了一个字典:
let dict = [String:Any]()
然后使用字典的updateValue
方法更新键值对:
dict.updateValue(someValue, forKey: “someKey”)
然后你最终将该dict上传到数据库:
let userAccountRef = self.dbRef.child("users").child(theUsersID).child(“userAccount”)
userAccountRef.updateChildValues(dict)
我的用户签名课程:
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
class CreateAccountController: UIViewController{
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
//Your firebase reference
var dbRef: FIRDatabaseReference!
//Current Timestamp in Seconds. You can convert the value later on
let timeStamp:NSNumber? = Int(NSDate().timeIntervalSince1970)
override func viewDidLoad() {
super.viewDidLoad()
//Firebase Reference to our database
self.dbRef = FIRDatabase.database().reference()
}
//Button to sign the user up
@IBAction func signUpButtonPressed(sender: UIButton) {
FIRAuth.auth()?.createUserWithEmail(emailTextField.text!, password: passwordTextField.text!, completion: {
//This is where your uid is created. You can access it by using user!uid. Be sure to unwrap it.
(user, error) in
print("my userID is \(user.uid)")
if error != nil{
print("Account Creation Error: \(error?.localizedDescription)")
return
}
//This constant holds the uid. It comes from the (user, error). The user argument has a uid string property
let currentUserID = user!.uid // which is the same as FIRAuth.auth()?.currentUser?.uid
//Here you initialize an empty dictionary to hold the keys and values you want uploaded to your database
let dict = [String:Any]()
//use the dictionary’s updateValue() method to update the values and matching keys
dict.updateValue(currentUserID, forKey: "userIDKey")
dict.updateValue(self.emailTextField.text!, forKey: "emailKey")
dict.updateValue(self.timeStamp!, forKey: "acctCreationDateKey")
//This gives you reference to your database, then to a child node named "users", then another node using the uid, and finally to another node named "userAccount". This final node is where you will keep your dictionary values for your database.
let userAccountRef = self.dbRef.child("users").child(currentUserID).child(“userAccount”)
//Here you upload your dictionary to the userAccountRef with the dictionary key/values you set above using the dict’s updateValue() method
userAccountRef.updateChildValues(dict)
})
}
}