0

Having the following structure in Firebase:

-events
     -Firebase Push ID for Event 1
         **-key: "DF2342"**
         -name: "Event 1"
         -createdOn : 12/12/12
     -Firebase Push ID for Event 2
         **-key: "AB1232"**
         -name: "Event 1"
         -createdOn : 12/12/12

Every key is autogenerated locally (DF2342 and AB1232) by the device where the app is running on although, I want to generate the key first on the device, then check if the key already exists in firebase database. If it does exist regenerate the key and try again. Here the code I'm using for that:

 let boardKey = self.keyGenHelper.generateUniqueKey()
        var validData = false
        while(!validData){
        databaseRef?.child("events").queryOrdered(byChild: "key").queryEqual(toValue: boardKey).observeSingleEvent(of: .childAdded, with: { (snapshot) in
            if !snapshot.exists() {
                let boardIdRef = self.databaseRef!.child("events").childByAutoId()
                boardIdRef.setValue(board.generateDictionary(key: boardKey))
                completion(boardKey, boardIdRef.key)
                validData = true
            }
        }, withCancel: {(error) in
            print(error)
        })
        }

The problem here is that the while loop keeps going on and on and never got response from firebase. What would be the best approach for me to accomplish this task?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
rudymatos
  • 321
  • 1
  • 3
  • 12
  • difficult, do you mean they are "keys to be shared with humans" ?? (sort of like "access codes" ?) – Fattie Dec 25 '16 at 00:38
  • There is no easy way to ensure unique value for a specific property across multiple child nodes. The solution is to store the values as keys in a secondary index (really just a lookup list). See this answer for a great explanation: http://stackoverflow.com/questions/35243492/firebase-android-make-username-unique – Frank van Puffelen Dec 25 '16 at 05:23

1 Answers1

3

Since your application requires that you can't use childByAutoId, a way to make sure you're generating unique IDs would be to store an additional table in firebase of just the IDs you've generated. For example:

"keys": {
  "DF2342": true,
  "AB1232": true,
  ...
}

Then when you generate your key you can do something like this:

let boardKey = self.keyGenHelper.generateUniqueKey()
var validData = false
while(!validData){
// check /keys in the database to see if we've already generated a key of this value
databaseRef?.child("keys").queryEqual(toValue: boardKey).observeSingleEvent(of: .childAdded, with: { (snapshot) in
    if !snapshot.exists() {
        let boardIdRef = self.databaseRef!.child("events").childByAutoId()
        boardIdRef.setValue(board.generateDictionary(key: boardKey))
        completion(boardKey, boardIdRef.key)
        validData = true
    }
}, withCancel: {(error) in
    print(error)
})

You also need to make sure you're writing the newly generated key to /keys.

Community
  • 1
  • 1
Forest Kunecke
  • 2,160
  • 15
  • 32
  • First , thanks for you answer although that's not what I want. I'm already using that to identify each event. These new keys are an easy-to-share keys (ex. DF2342 and AB1232) and I need to make sure there is not another event already created with this values. – rudymatos Dec 25 '16 at 00:16