-1

What I'm wanting to accomplish is save a score to firebase that has two values attached to it. Here's the code that writes the score to firebase.

func writeToFirebase() {
    DispatchQueue.global(qos: .userInteractive).async {
        self.ref = Database.database().reference()
        if GameManager.instance.getTopScores().contains(GameManager.instance.getGameScore()) {
            self.ref?.child("user")
                .child(GameManager.instance.getUsername())
                .child(String(GameManager.instance.getGameScore()))
                .updateChildValues( [
                    "badge":GameManager.instance.getBadgeLevel(),
                    "vehicle": GameManager.instance.getVehicleSelected()
                ]
            )
        }
    }
}

The issue I'm having is when a new score is saved with its values it sometimes overwrites the other scores. This seems to be random and its not when they're the same score or anything like that. Sometimes it will only overwrite one score and sometimes multiple. I'm watching firebase and I can see it being overwritten, it turns red and then is deleted. Sometimes the new score being added will be red and get deleted. The score doesn't need to be a child, but I don't know how to attach values to it if it's not. Any help is appreciated

enter image description here

Jay
  • 34,438
  • 18
  • 52
  • 81
Dave
  • 27
  • 6
  • Three things. 1) Please don’t include images in your questions if a text version is available. Include code and structures as text. To get your Firebase structure, use the Firebase console->Export JSON and copy and paste a snippet of your structure. 2) be sure to be more clear about what your structure is. I assume Popper is the user name and is a child of /user? 3) DispatchQueues are not needed with Firebase as calls for both reading and writing are asynchronous and will not tie up your UI. Other than that, the code in your question is good and works correctly. Remove Dispatch and try again. – Jay Feb 23 '20 at 13:31
  • 1
    A couple of thoughts. You may have an observe on this node (/users) that's firing when child nodes are updated but the data isn't valid so it writes nil. I would add a breakpoint in this function at `self.ref = Database.` and see if it's called twice. Also, this may be a persistence issue - see this question and my answer [here](https://stackoverflow.com/questions/57972133/firebase-child-query-coming-up-nil-after-deleting-a-key-then-adding-it-back/57979435#57979435). Lastly, see [this question](https://stackoverflow.com/questions/58356971/firebase-child-nodes-are-randomly-deleted) – Jay Feb 23 '20 at 13:40
  • Hey Jay thanks for the answer. We just do this as a hobby so we appreciate the advice on the forum etiquette. You were right, we were calling it twice. Problem solved! Can't believe we missed that. Thanks again, really appreciate it – Dave Feb 25 '20 at 05:01

1 Answers1

0

This issue seems to happen occasionally so I am going to post my comment as an answer.

There are situations where an observer may be added to a node and when data changes in that node, like a write or update, it will fire that observer which may then overwrite the existing data with nil.

You can see this visually in the console as when the write occurs, you can see the data change/update, then it turns red and then mysteriously vanishes.

As suggested in my comment, add a breakpoint to the function that performs the write and run the code. See if that function is called twice (or more). If that's the case, the first write is storing the data properly but upon calling it a second time, the values being written are probably nil, which then makes the node 'go away' as Firebase nodes cannot exist without a value.

Generally speaking if you see your data turn red and vanish, it's likely caused by nil values being written to the node.

Jay
  • 34,438
  • 18
  • 52
  • 81