0

Running a Firebase closure such as:

databaseRef.observe(.childAdded) { (snapshot) in
   ...
}

When first run it will go and get the data and will also execute its closure whenever data is added. This is as it should be. However, when you first fire off this method, and there is no data to get, the closure never returns. In this way there is no way to tell if there is no data or if all of the data just hasn't been gotten yet. Without the closure firing, we cannot look at the snapshot to see if it exists.

Given the documentation indicates that you can interrogate the snapshot to see if it exists or if the values are nil, there must be a way to get called back initially. Again subsequent data added will call back this closure and the closure will come back if there is data there initially.

What am I missing about getting an initial callback if there is no data?

Update:

To provide a working solution which was not provided in the links given indicating this was a duplicate. The reason for the issue - which Frank answered perfectly here and in the thread links he provided - was due to the the way .childAdded works. Frank indicated that one can call both a .value and a .childAdded on the same query and the initial data will not be loaded twice. Based on this key information, I went about handling this in the following way:

databaseRef.observeSingleEvent(.value, with: { (valueSnapshot) in
   if !valueSnapshot.exists() {
      [do stuff based on the absence of data]
   }
   databaseRef.observe(.childAdded) { (childSnapshot) in
      [do stuff based on children present and when children added]
   }
}

The outer event will fire once only. The inner event will be set as a listener so future children added will be executed within its closure only.

C6Silver
  • 3,127
  • 2
  • 21
  • 49

1 Answers1

1

A .childAdded event is fired for each child node that exist initially, or that is added later. If there are child nodes, .childAdded is not fired.

If you want to know whether data exists, you should observe the .value event.

If you observe both .child... and .value on the same reference/query, Firebase will only retrieve the data once. So there is no extra data transfer to observe both events.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • The key you have indicated above is that you can observe .child and .value on the same reference without retrieving the data more than once. In that case would one want to `observeSingleEvent` based on `.value` for the first query and the second query would be the regular child observe? I ask because I don't want continuous observation based on .value and this was not addressed in the links you provided. Thanks. – C6Silver Jun 08 '20 at 02:22
  • 1
    If you only care about the initial data being completed, a `observeSingleEvent` of `.value` would indeed make sense. – Frank van Puffelen Jun 08 '20 at 03:50