2016-06-26 12 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]" 
    } 
} 

그러면 코드가 조금 변경됩니다. 당신이 아직하지 않은 경우 당신은 당신의 데이터베이스에 emails 지점을 가지고 할 것은 당신이 (AN users 분기를 가질 수 있기 때문에 이유가 궁금하네요 한편

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

: userLookUpByEmail를 호출

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) 
     }) 
} 

) 이메일을 포함하여 모든 사용자 데이터를 저장합니다. 이렇게하면 데이터 구조가 훨씬 더 깨끗하고 신뢰할 수 있습니다. 다시 말하지만, 저는 당신의 필요를 정확히 알지 못하기 때문에 여기에서 궁금합니다.

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

'불특정 색인 사용하기 '오류. 더 나은 성능을 위해 보안 규칙에/이메일에 ".indexOn": "email"을 추가하십시오. 내 규칙은'{ "규칙"과 같아야합니다 : { ".read": "인증 = 널 (null)", "에 .write": "인증 = 널 (null)" "/ 이메일"{ ".indexOn을" "이메일" } } }'? – user5812721

+1

@ user5812721 이것은 오류가 아닙니다. 코드가 내부 firebase 성능을 위해 사용되기 때문에 코드없이 작동해야합니다. 'auth! = null', '.write': "auth! = null", "emails": { ".indexOn": "당신이 찾고있는 규칙은 다음과 같습니다 : email "}}}' – adolfosrs

+0

룰을 추가하기 전에 스냅 샷 키가 발견되었지만 이제는 항상 nil입니다. 또한'')''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"의 배열로 이메일을 분할합니다. 그런 다음 새로운 문자로 새 문자를 다시 결합하여 "email @ example • com"을 만듭니다.

이전 전자 메일이 필요한 경우 역순으로 동일한 작업을 수행 할 수 있습니다.

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

그런 다음 마지막으로, 원래의 질문에 대해,이 함수는 그러나이

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 
} 

처럼 쓸 수있는이

emails: 
    [email protected]•com: UID123456789 

처럼 나무를 포맷 할 수있는 것이 가능 너야 매회 "무"을 얻을 것입니다. 이것은 observeSingleEventOfType이 클로저이기 때문입니다. 이는 앱의 백그라운드에서 실행됨을 의미합니다.이 때문에 사용자 ID가 클로저 내부에서 변경되기 전에 반환 될 수 있습니다. userID를 반환하는 대신 closure 내부의 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'라는 클래스의 var에 저장 한 후'userLookUpByEmail'을 호출 한 후에 변수를'user2uid'에 저장했지만'temp_uid'는 여전히 올바른 값을받지 못합니다. – user5812721

+1

@ user5812721 기본적으로 클로저 외부에 아무것도 넣을 수 없습니다. 대부분의 경우, 브래킷 바깥에 놓은 것이 제대로 작동하지 않습니다. 시계를이기려고 노력하는 것은 효과가 없습니다. 클로저 안에'snapshot'으로하고 싶은 모든 것을 넣을 필요가 있습니다. 이 값들을 가지고 무엇인가를하기 원한다면, 함수를 만들고 그 안에 넣으십시오. 예를 들어'doSomethingWith (userID)'를 넣으면 원하는 것을 넣을 수 있습니다. – skunkmb

+0

명확히하려면 ... 클로저/블록 외부에 데이터를 저장할 수 있지만 스냅 숏이 블록 내부에서 유효 할 때까지는 해당 데이터를 처리하지 않아야합니다. 예를 들어 블록 외부에 클래스 레벨 배열 self.myArray (tableview 데이터 소스)를 가질 수 있습니다. 배열을 블록 내부의 스냅 샷에서 채우고 어레이가 채워진 후 다시 블록 내부에서 다시로드되도록 tableview에 지시합니다. – Jay