Как сравнить определенное значение с дочерними значениями Firebase? - PullRequest
0 голосов
/ 12 декабря 2018

Описание

Я использую базу данных реального времени с Google Firebase и пытаюсь проверить, совпадает ли дочернее значение с определенным значением.

enter image description here

У меня есть коллекция пользователей , которую я храню в базе данных Firebase.Каждый объект пользователя содержит поле токена.

{
  "users" : {
    "-LTTvwvs5OMaKO6pyZb-" : {
      "accountId" : 1001,
      "createdAt" : "2018-12-11 15:22:55",
      "email" : "john@doe.com",
      "fcmToken" : "duhfkNCIKW8:APA91bGgbzVCcagIhIw8DYFN_LVIKcjtyUiZEk0mxd3QLYkxRjQuGXdSfZMPcvw4maytKef-GXMEFrpH_lLz5QY0OV7qvwtyOll9jjKMH0vEWJUGIyp1iGQ4NZIMQE3kmZ-jZ8kF-1Bc",
      "updatedAt" : "2018-12-11 15:22:55"
    },
    "-LTTwH8BdMe6W1lmhb-b" : {
      "accountId" : 1001,
      "createdAt" : "2018-12-11 15:24:22",
      "email" : "john@doe.com",
      "fcmToken" : "e_86qbjpjLE:APA91bHyVEgeH8aZMrn7213ws0-oXeTpdFRwY-FDcAbkQkMnaCdSNp9he6-AvQ0AUIsX-TywAxuWLCZ9BqIRsuyx1ZD9reD6wMeqtfP1swONq-rF6vQzet61DUbLfPXdlZhvxEjI9Cpz",
      "updatedAt" : "2018-12-11 15:24:22"
    },
    "-LTTwNcoaQYri1paUwVD" : {
      "accountId" : 1001,
      "createdAt" : "2018-12-11 15:24:48",
      "email" : "john@doe.com",
      "fcmToken" : "e_86qbjpjLE:APA91bHyVEgeH8aZMrn7213ws0-oXeTpdFRwY-FDcAbkQkMnaCdSNp9he6-AvQ0AUIsX-TywAxuWLCZ9BqIRsuyx1ZD9reD6wMeqtfP1swONq-rF6vQzet61DUbLfPXdlZhvxEjI9Cpz",
      "updatedAt" : "2018-12-11 15:24:48"
    },
    "-LTUv-aBEaQDrvvMrlAG" : {
      "accountId" : 1001,
      "createdAt" : "2018-12-11 18:58:25",
      "email" : "john@doe.com",
      "fcmToken" : "eOaNDdd2DXI:APA91bGzgcudlScng9TuEgSUY9ahA2pXVgl7AKxmkdX9ubw6uA5livNcJUlcI5pHYwn9fI7kc_9od5AbGrXm4wZPul_gI7qcGarTQTwkxq9zEKgovX0nWDDpDtNCLiWIaON6MWu5XLbW",
      "updatedAt" : "2018-12-11 18:58:25"
    }
  }
}

iOS Swift 4

С другой стороны, на моем телефоне у меня есть 1 токен

Отл.

. "DuhfkNCIKW8: APA91bGgbzVCcagIhIw8DYFN_LVIKcjtyUiZEk0mxd3QLYkxRjQuGXdSfZMPcvw4maytKef-GXMEFrpH_lLz5QY0OV7qvwtyOll9jjKMH0vEWJUGIyp1iGQ4NZIMQE3kmZ-jZ8kF-1Bc"

Я пытаюсь сравнить этот маркер ?? всех маркеров в моей базе данных Firebase


Код

func storeToFirebaseDatabase() {

    let ref = Database.database().reference()
    let usersRef = ref.child("users")

    let id = usersRef.childByAutoId().key
    let fcmToken = UserDefaults.standard.string(forKey: "fcmToken")

    consoleLog(fcmToken)

    let values =
        ["accountId": loginAccount.id!,
         "email": loginAccount.username,
         "fcmToken": fcmToken
            ] as [String : Any]

    ref.root.child("users").observe(DataEventType.value, with: { (snapshot) in

        if snapshot.exists() {

            for child in snapshot.children {
                let token = (child as! DataSnapshot).childSnapshot(forPath: "fcmToken").value as! String

                if(token != fcmToken){

                    usersRef.child(id!).setValue(values, withCompletionBlock: { (err, ref) in
                        if err != nil {
                            print(err.self as Any)
                            return
                        }
                        print("Successfully saved user in Firebase DB")

                    })

                    break
                }

            }

        } 


    }) { (error) in
        print(error.localizedDescription)
    }
}

Результат

По некоторым причинам токен продолжает вставляться, кажется, что мой if-check работает вообще.

Как можно отладить это дальше?

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Ваша проблема в том, что вы сравниваете токен в операторе if с каждым пользователем, но вам нужно посмотреть, есть ли у пользователя его или нет

ref.root.child("users").observe(DataEventType.value, with: { (snapshot) in

    if snapshot.exists() {

      let tokens =  snapshot.children.forEach { ($0 as! DataSnapshot).childSnapshot(forPath: "fcmToken").value as! String }

        if ! tokens.contains(fcmToken) {

             // no user has that token ,  set the user here
        }
    }

}
0 голосов
/ 13 декабря 2018

Возможно, я неправильно понимаю вопрос, но похоже, что вы хотите создать пользователя, если данный токен еще не существует в Firebase.

Простой запрос разрешил бы это;

let usersRef = self.ref.child("users")
let tokenToCompare = "duhfkNCIKW8APA9..." //abbreviated
let query = usersRef.queryOrdered(byChild: "fcmToken").queryEqual(toValue: tokenToCompare)
query.observe(.value, with: { snapshot in
    if snapshot.exists() {
        print("token exists, do not create user")
        return
    } else {
        print("no existing token found, create user")
    }
})

Если токен существует, он напечатает это сообщение и не будет продолжать.Если токен не существует, вы можете вставить код для создания пользователя.

... и если вы хотите, чтобы все было денормализовано, то добавьте отдельный узел для отслеживания существующих токенов

existing_tokens
   jasoijaisas9: true
   99i9kmkdodkf: true
   duhfkNCIKW8APA9: true

тогда вы можете избежать более тяжелого запроса с помощью простого наблюдения, которое намного легче.

let existingTokensRef = self.ref.child("existing_tokens")
let tokenToFindRef = existingTokensRef.child("duhfkNCIKW8APA9")
tokenToFindRef.observeSingleEvent(of: .value, with: { snapshot in
    if !snapshot.exists() {
        print("ok to create user")
    } else {
        print("token exists! Dont create user")
    }
})

Единственное, что нужно смотреть с помощью этой техники, - это не иметь специальных символов в ключах.

0 голосов
/ 12 декабря 2018

Вместо setValue вы можете использовать HashMap () с updateChildValues, он будет переопределять, если токен отличается, и если он равен, он не будет обновлять токен и переопределять текущий.

И вы запрещаете запрашивать у вашей базы данных это значение и сравнивать его с оператором if.

Вы должны заменить эту строку на updateChildValues вместо setValue

usersRef.child(id!).setValue(values....

Takeсмотрите здесь:

https://firebase.google.com/docs/database/ios/read-and-write

Из документации

Для одновременной записи в определенные дочерние узлы без перезаписи других дочерних узлов используйте метод updateChildValues.

При вызове updateChildValues ​​вы можете обновить дочерние значения нижнего уровня, указав путь к ключу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...