2017-01-25 63 views
0

爲我的配置文件設置視圖控制器。登錄後,個人資料頁面可以無誤地顯示,但註冊時,按下位於視圖控制器底部的聯繫人按鈕時,應用會崩潰,如下所示。在swift中顯示firebase子從user.uid到用戶名3

的方法:

用戶註冊:

func signUp(_ email: String, usersname: String, password: String, data: Data!, loginHandler: LoginHandler?) { 

    FIRAuth.auth()?.createUser(withEmail: email, password: password, completion: { (user, error) in 

     if error != nil { 
      // Show error to user 
      self.handleFirebaseErrors(err: error as! NSError, loginHandler: loginHandler) 

     } else { // success creating user 

      if user?.uid != nil { // if there is a valid user id 

       // Store user to database 
       self.setUserInfo(user, usersname: usersname, email: email, password: password, data: data!) 

       // Log In the user 
       self.login(email: email, password: password, loginHandler: loginHandler) 
      } 
     } 
    }) 

} 

如在註冊(),setUserInfo()被調用,其中包含的圖像,然後調用saveUser()

保存用戶

func saveUser(_ user: FIRUser!, usersname: String, email: String, password: String) { 

    // Create the user dictionary info 
    let userInfo = ["email": user.email!, "password": password, "usersname": usersname, "uid": user.uid, "photoUrl": String(describing: user.photoURL!)] 

    // create user reference 
    let userRef = DataService.Instance.dbRef.child("riders").child(user.uid) 

    // Save the user info in the database 
    userRef.setValue(userInfo) 

} 

登錄

func login(email: String, password: String, loginHandler: LoginHandler?) { 

    FIRAuth.auth()?.signIn(withEmail: email, password: password, completion: { (user, error) in 

     if error != nil { 
      self.handleFirebaseErrors(err: error as! NSError, loginHandler: loginHandler) 
     } else { 
      loginHandler?(nil, nil) 
     } 
    }) 

} 

這裏的問題是saveUser(): 目前,火力顯示user.uid,但我想讓它顯示的用戶的用戶名。

let userRef = DataService.Instance.dbRef.child("riders").child(usersname) 

與上面的代碼中,一旦按鈕被按下在RidersVC觸點,它崩潰應用程序,錯誤:

fatal error: unexpectedly found nil while unwrapping an Optional value 

上MyProfileVC的56行:

let imageUrl = String(user.photoUrl) 

不限想法,我可以如何讓用戶名顯示爲「騎手」的孩子,而不是沒有崩潰的user.uid?任何幫助,將不勝感激。

MyProfileVC.swift

if FIRAuth.auth()?.currentUser == nil { 

     let vc = UIStoryboard(name: "Rider", bundle: nil).instantiateViewController(withIdentifier: "Login") 
     present(vc, animated: true, completion: nil) 

    } else { 

     dbRef.child("riders/\(FIRAuth.auth()!.currentUser!.uid)").observe(.value, with: { (snapshot) in 
      DispatchQueue.main.async(execute: { 


       let user = User(snapshot: snapshot) 
       self.username.text = user.usersname 
       self.email.text = FIRAuth.auth()?.currentUser?.email 

       let imageUrl = String(user.photoUrl) 

火力地堡數據庫結構:(我怎麼想它是)

{ 
    "riders" : { 
    "rider 1" : { 
     "email" : "[email protected]", 
     "password" : "whatever", 
     "photoUrl" : "https://firebasestorage.googleapis.com/...", 
     "usersname" : "rider 1" 
    } 
    } 
} 

User.swift

struct User { 

let usersname: String! 
let email: String! 
let password: String! 
let photoUrl: String! 
var ref: FIRDatabaseReference? 
var key: String 


init(snapshot: FIRDataSnapshot) { 
    key = snapshot.key 
    ref = snapshot.ref 

    let snapshotValueUsersname = snapshot.value as? NSDictionary 
    usersname = snapshotValueUsersname?["usersname"] as? String 

    let snapshotValueEmail = snapshot.value as? NSDictionary 
    email = snapshotValueEmail?["email"] as? String 

    let snapshotValuePass = snapshot.value as? NSDictionary 
    password = snapshotValuePass?["password"] as? String 

    let snapshotValuePhoto = snapshot.value as? NSDictionary 
    photoUrl = snapshotValuePhoto?["photoUrl"] as? String 

} 

火力地堡結構 - (現在的樣子)

{ 
    "drivers" : { 
    "RideRequests" : { 
     "europeanjunkie" : { 
     "active" : true, 
     "latitude" : "45.267", 
     "longitude" : "-66.059", 
     "userId" : "5c17ByRJljZFcM703Vqn5eSFwYJ3", 
     "username" : "europeanjunkie" 
     } 
    } 
    }, 

    "riders" : { 
    "5c17ByRJljZFcM703Vqn5eSFwYJ3" : { 
     "email" : "[email protected]", 
     "password" : "whatever", 
     "photoUrl" : "https://firebasestorage.googleapis.com", 
     "uid" : "5c17ByRJljZFcM703Vqn5eSFwYJ3", 
     "usersname" : "europeanjunkie" 
    } 
    } 
} 
+0

您必須更改數據庫的數據結構。您將車手的孩子保存爲'uid'('userRef = DataService.Instance.dbRef.child(「riders」)。child(user.uid)')。但是,您希望將騎手的孩子作爲「用戶名」('DataService.Instance.dbRef.child(「騎手」)。child(用戶名)')。當然,它是零。 – WeiJay

+0

代碼存在很多問題,但最重要的是您的User類中的快照正在做什麼。您可以發佈您的Firebase結構和您的用戶類的片段嗎?答案很簡單,但需要首先看到。 – Jay

+0

@Jay添加了User.swift和Firebase結構 – LizG

回答

1

這裏有一些東西要考慮 - 一點點,一些或全部可能讓你朝着正確的方向前進。另外,您可能會刪除所有DispatchQueue調用,因爲Firebase會爲您完成大部分繁重的工作,並且具有正確的代碼結構,因此不需要這些調用。我們使用的每個用戶的VAR UID識別它們(他們的 '鑰匙')

相匹配的一流

結構

1)SWIFTY用戶類

class UserClass { 
    var usersname = "" 
    var email = "" 
    var password = "" 
    var photoUrl = "" 
    var uid = "" 

    init(withSnapshot: FIRDataSnapshot) { 
     let dict = withSnapshot.value as! [String:AnyObject] 

     uid = withSnapshot.key 
     usersname = dict["usersname"] as! String 
     email = dict["email"] as! String 
     password = dict["password"] as! String 
     photoUrl = dict["photoUrl"] as! String 
    } 
} 

users 
    uid_0 
    email: "[email protected]" 
    password: "myPassword" 
    photoUrl: "http://www.url.com" 
    usersname: "Bill" 
    uid_1 
    email: "[email protected]" 
    password: "aPassword" 
    photoUrl: "http://www.anotherUrl.com" 
    usersname: "Leroy" 

再次注意,用戶及其關聯信息存儲在每個子節點的/ users節點中,該子節點以該用戶爲關鍵字。

而一些讀取uid_0的代碼打印出uid和名稱。此代碼是一次性的,因此它讀取uid_0,但不會將觀察者留在節點上。

let userRef = rootRef.child("users/uid_0") 
userRef.observeSingleEvent(of: .value, with: { snapshot in   
    let aUser = UserClass(withSnapshot: snapshot) 
    print("uid \(aUser.uid) has name \(aUser.usersname)") 
}) 

現在Geofire節點想這樣的事情

user_locations 
    uid_0 
    //geofire data 
    uid_1 
    //geofire data 

所以,現在有用戶節點和他們的位置有直接的關係。

一般來說,將節點名稱(鍵是靜態數據)與它們包含的數據(動態數據)分離是一個好主意。

根據最初問題的結構,想象一下,如果'europeanjunkie'將他的名字改爲'europeanjunkieDude'。你提到的每一個地方'europeanjunkie'都必須改變 - 如果它被用作關鍵字,整個節點將不得不被讀入,刪除,更新和重寫。

使用由Firebase,uid和childByAutoId()創建的子鍵可以消除該問題。

希望有幫助!

0

在我看來,如果你想查詢用戶名作爲關鍵字。有兩種可能的方法來構建你的字典。

首先,使用childByAutoId,用戶名和用戶ID將處於同一級別,因此您可以獲得您喜歡的值。

{ 
    "riders" : { 
    "-KQaU9lVcUYzIo52LgmN" : { 
     "email" : "[email protected]", 
     "password" : "whatever", 
     "photoUrl" : "https://firebasestorage.googleapis.com/...", 
     "usersname" : "rider 1", 
     "userid" : "rider 1" 
    } 
    } 
} 

其次,使username作爲車手的孩子。但是,會有很多麥克。

{ 
    "riders" : { 
    "username" : { 
     "email" : "[email protected]", 
     "password" : "whatever", 
     "photoUrl" : "https://firebasestorage.googleapis.com/...", 
     "userid" : "rider 1" 
    } 
    } 
} 
+0

如果我嘗試以除.child(user.uid)之外的任何其他方式執行此操作,那麼它會崩潰應用程序,因爲它不會記錄在用戶中。 – LizG

相關問題