1

[Disclaimer] I have personally posted and answered this question after having struggled with it myself and, relevantly, noticed that many people still do

Context

I am developing an iOS mobile application and - for this particular project - decided to use the Firebase Realtime Database as my backend infrastructure.


Problem

When querying data at a specific node using the .observeSingleEvent(of:with:) method, I always find myself retrieving either cached or old data rather than the newly updated one.

In some cases, calling the method twice in a row retrieves the desired server data.


Attempts

  1. Used .keepSynced(true) at the relevant node which, according to the Firebase documentation

    automatically downloads the data at these locations and keeps it in sync even if the reference has no active listeners

Jad Ghadry
  • 245
  • 2
  • 25
  • `observeSingleEventOf` and disk persistence don't work well together: your closure immediately receives the value from cache, while the client goes to retrieve the latest value from the database, and updates its cache. See my explanation here for why that is: https://stackoverflow.com/questions/34486417/firebase-offline-capabilities-and-addlistenerforsinglevalueevent. The solution is to use a regular listener: `.observe(`. – Frank van Puffelen Sep 24 '18 at 13:22
  • Thank you for your comment @FrankvanPuffelen. I have thoroughly read your explanation multiple times, and it's far beyond great. Nonetheless, although the problem underlined by this question is the same, the source of the issue is very different. – Jad Ghadry Sep 24 '18 at 13:39
  • In that case, can you update your question to show how to reproduce the problem? See [how to create a minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) for how to do this, and why this is useful. – Frank van Puffelen Sep 24 '18 at 13:48

1 Answers1

2

Overview

Going through the documentation, you notice that there are two primary ways of querying data from the Firebase Realtime Database into your iOS mobile application

  1. The .observe(_:with:) method which, according to the Firebase Documentation, continuously listens for changes at a particular node and triggers the callback every time the data changes at the latter.

    This method is triggered once when the listener is attached and again every time the data, including any children, changes. The event callback is passed a snapshot containing all data at that location, including child data. If there is no data, the snapshot will return false when you call exists() and nil when you read its value property.

  2. The .observeSingleEvent(of:with:) method which, according to the Firebase Documentation, is called exactly once.

    In some cases you may want a callback to be called once and then immediately removed, such as when initializing a UI element that you don't expect to change. You can use the observeSingleEventOfType method to simplify this scenario, [in which] the event callback [is triggered] once and then does not trigger again.


Problem

After going through the different possible methods of querying your data, you've realized that the .observeSingleEvent(of:with:) method suits better your current database-reading needs. However, implementing it in your application keeps on retrieving cached and old data no matter how many times you modify your database. You've called the .keepSynced(true) at the relevant database reference, yet in vain. You've opted for the .observe(_:with:) method instead, and everything starts to work perfectly fine.

So what might be the issue?


Solution

The reason you might be going through this problem is perfectly logical if you have invalid database security rules. These can easily prevent you from retrieving your desired data and synchronizing your realtime database.

Let's assume you are trying to synchronize the myRef database reference. You need to set the correct rules that allow reading from this database reference - something along the lines of ".read" = true".

[Warning] Please be careful with these database security rules. Incorrect rules can lead to drastically undesired behaviors, such as people illegally reading and/or writing from/into your database. A good video on how to set flawless security rules is The key to firebase security - Google I/O 2016

Jad Ghadry
  • 245
  • 2
  • 25