2016-06-26 37 views
2

的UID我第一次嘗試實例化每個用戶在數據庫中,像這樣:發現通過電子郵件在火力地堡

emails : { 
    email: "[email protected]" { 
     uid: "x" 
    } 
} 

我很快發現,我不能存儲電子郵件,因爲它有一個@.。我本來是想做一個用戶擡頭看起來像這樣:

func userLookUpByEmail (email: String) -> String { 
    var userID: String = "nil" 

    ref.queryOrderedByChild("emails").queryEqualToValue(email).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
      if snapshot.value != nil { 
       print(snapshot.value) 
       userID = snapshot.value as! String 
      } 
      else { 
       print ("user not found") 
       userID = "nil" 
      } 
    }) 
    return userID 
} 

但是,我意識到這將無法正常工作。從提供電子郵件中接收UID的有效方法是什麼?

+1

你的數據結構是不是有效的JSON。請用有效的JSON更新您的問題。 –

+0

像這樣的東西似乎是最簡單的數據結構來做你想要的:http://stackoverflow.com/questions/37897656/firebase-security-find-other-users-via-email/37909700#37909700 –

回答

5

回答您的問題,因爲您不能將電子郵件作爲子密鑰,您可以通過以其他方式設置uid作爲密鑰,並將電子郵件設置爲孩子

emails : { 
    uid: { 
     email: "[email protected]" 
    } 
} 

然後你的代碼會改變一點點。

func userLookUpByEmail (email: String, completionHandler: (result: String) -> Void) { 
    var userID: String = "nil" 
    ref.child("emails").queryOrderedByChild("email").queryEqualToValue(email).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
       if snapshot.value != nil { 
        print(snapshot.key) 
        userID = snapshot.key as! String 
       } 
       else { 
        print ("user not found") 
        userID = "nil" 
       } 
       completionHandler(userID) 
     }) 
} 

調用userLookUpByEmail

userLookUpByEmail(email) { 
    (result: String) in 
    print("\(result)") 
} 

在另一方面,我不知道爲什麼你在你的數據庫有一個emails分支,因爲你可以有一個users分支(如果你沒有還)並存儲任何用戶數據,包括電子郵件。這將使您的數據結構更加乾淨可靠。再次,我想知道這裏,因爲我不完全知道你的需求。

users : { 
    uid: { 
     email: "[email protected]", 
     name: "Jerry Maguire", 
     ... 
    } 
} 
+0

我得到錯誤'使用未指定的索引。考慮在/ emails中添加「.indexOn」:「email」以達到您的安全規則,以獲得更好的性能。如果我的規則看起來像「{ 」規則「:{ 」.read「:」auth!= null「, 」.write「:」auth!= null「 」/ emails「{ 」.indexOn「: 「email」 } } }'? – user5812721

+1

@ user5812721這不是錯誤。您的代碼應該沒有它,因爲它只是爲了實現內部的Firebase性能。您要查找的規則是:{「rules」:{「.read」:「auth!= null」,「.write」:「auth!= null」,「emails」:{「.indexOn」:「電子郵件「}}}' – adolfosrs

+0

在添加規則之前,會找到快照鍵,但現在它始終爲零。在我編寫'print(userid)'''''''''之後,它也沒有出現,所以我認爲這是一個錯誤。在添加規則之前,我在第一個if語句中打印了快照鍵,並且始終正確。 – user5812721

3

首先,你是正確的,你不能在數據庫中存儲某些字符。按照火力地堡文檔,(https://firebase.google.com/docs/database/ios/structure-data

如果你創建自己的密鑰,它們必須是UTF-8編碼,最多768個字節就可以了,不能包含。,$,#,[,] ,/或ASCII控制字符0-31或127.

但是,您可以看到,「@」符號不是其中之一。至於點,你可以有一個功能,用另一個字符替換點。例如, 」•」。下面是一個例子:

func createNewEmail(oldEmail: String) -> String{ 
    return oldEmail.componentsSeparatedByString(".").joinWithSeparator("•") 
} 

它是如何將電子郵件拆分爲「email @ example」和「com」數組。然後,再加入他們的新角色,如果你需要的舊電子郵件創建「電子郵件@例如•COM」

,你可能只是做同樣的事情相反。

func getOldEmail(newEmail: String) -> String{ 
    return newEmail.componentsSeparatedByString("•").joinWithSeparator(".") 
} 

然後,您可以格式化你的樹像這樣

emails: 
    [email protected]•com: UID123456789 

最後,對於你原來的問題,該功能可以寫成這樣

func userLookUpByEmail (email: String) -> String { 
    let newEmail = createNewEmail(email) 
    var userID: String = "nil" 

    ref.child("emails").child(newEmail).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
      if snapshot.value != nil { 
       print(snapshot.value) 
       userID = snapshot.value as! String 
      } 
      else { 
       print ("user not found") 
       userID = "nil" 
      } 
    }) 
    return userID 
} 

但是,它可能是你每次都會得到「零」。這是因爲observeSingleEventOfType是一個閉包。這意味着它運行在你的應用程序的後臺。因此,可能會在封閉內部更改之前返回userID。您可能想要在封閉內部運行基於userID的任何代碼,而不是返回userID。例如,而不是這樣做:

func userLookUpByEmail (email: String) -> String { 
    let newEmail = createNewEmail(email) 
    var userID: String = "nil" 

    ref.child("emails").child(newEmail).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
      if snapshot.value != nil { 
       print(snapshot.value) 
       userID = snapshot.value as! String 
      } 
      else { 
       print ("user not found") 
       userID = "nil" 
      } 
    }) 
    return userID 
} 

doSomethingWith(lookUserUpByEmail([email protected])) 

你可以這樣做:

func userLookUpByEmail (email: String){ 
    let newEmail = createNewEmail(email) 
    var userID: String = "nil" 

    ref.child("emails").child(newEmail).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in 
      if snapshot.value != nil { 
       print(snapshot.value) 
       userID = snapshot.value as! String 
       doSomethingWith(userID) 
      } 
      else { 
       print ("user not found") 
       userID = "nil" 
       doSomethingWith(userID) 
      } 
    }) 
} 
+0

我將它保存到一個名爲'temp_uid'的類中,然後在調用'userLookUpByEmail'後將該變量保存到'user2uid'中,但temp_uid仍然沒有及時收到正確的值。 – user5812721

+1

@ user5812721你基本上不能在關閉之外放置任何東西。大部分情況下,你放在括號外的任何內容都不能正常工作。試圖擊敗時鐘不起作用。你需要在閉包中放置''snapshot''所需的_everything_。如果你想對這些值做些什麼,做一個函數,然後把它放在裏面。例如,我把'doSomethingWith(userID)'放在哪裏,你可以放任何你想要的東西。 – skunkmb

+0

澄清...您可以將數據存儲在閉包/塊之外,但不應對該數據採取行動,直到快照在塊內有效。因此,例如,您可以在塊外部有一個類級別的數組self.myArray(tableview數據源)。你可以從塊內部的快照中填充該數組,並且還會告訴你的tableview在數組填充後再次從塊內部重新加載自己。 – Jay