PouchDB doesn't sync DB results when App first loads on Mobile device


#1

I’m currently building an App which uses PouchDB & Cloudant for Offline / Online data access. I’ve based it off the code in this tutorial, and my todos.ts file is almost identical (very minor tweaks to connect to Cloudant instead of CouchDB.

I’ve run into a problem where whenever the app is first loaded on my device, it doesn’t show any data from Cloudant, even though data is there. The same thing happens if I clear the cache in the browser (on my PC) and then ionic serve the app. I get the following PouchDB errors in the console:

<<cloudant address>> 
Failed to load resource: the server responded with a status of 404 (Object Not Found)
The above 404 is totally normal. PouchDB is just checking if a remote checkpoint exists.
<<cloudant address>> 
Failed to load resource: the server responded with a status of 400 (Bad Request)
The above 400 is totally normal. PouchDB is just detecting if the remote supports the _bulk_get API.
<<cloudant address>> 
Failed to load resource: the server responded with a status of 404 (Object Not Found)
The above 404 is totally normal. PouchDB is just checking if a remote checkpoint exists.

(I’ve removed the actual address of my cloudant server and replaced it with <<cloudant address>)

The current workaround is to refresh the page (either on the mobile device or in the browser on my PC) and the data from cloudant loads fine.

My interpretation of the aforementioned errors is that the Pouchdb database doesn’t already exist (on the device or in the cahce), therefore the errors are displayed. This is to be expected, however I would expect the app to then create the PouchDB database and populate it with the data from Cloudant (which is does) and then display this data on screen (which it does not).

Is there anything I need to change in my code to get this to occur? I’m guessing I somehow need to tell the application to refresh the screen if this error occurs? I’m not sure of the best way to go about doing this.


#2

All of the “errors” you list are actually normal PouchDB operations, hence the “this is totally normal” messages. :slight_smile:

Most likely the error you’re seeing is something else. Did you check the Network tab in the Dev Tools for any other errors in connecting to Cloudant? Did you enable CORS on Cloudant?

If a PouchDB database doesn’t already exist, then PouchDB will create one. That shouldn’t cause any errors.


#3

Hi @nolanlawson, I’m convinced the issue is not with PouchDB and more with my code (which I mostly copied from the tutorial). The reason for this is because I have performed the following checks:

  • I clear my Chrome browser cache and check the PouchDB tab in my Dev tools (I have downloaded the PouchDB Chrome Extension). This shows that no PouchDB databases exist.
  • I run ionic serve and observe that my application displays no data, however when I check the PouchDB tab in my Dev tools I can see that the correct database has been created and populated with the correct values, as per the picture below.

  • I’ve also checked the Network tab in my Dev tools and no issues there.

This issue is that the values are not displaying on-screen (only when the app is very first loaded), so I’m thinking that there is something wrong with my code somewhere, and not with my connection to Cloudant. My project is located on GitHub here - is there anything specific I’ve neglected to do?


#4

Clearing the browser cache does not actually clear IndexedDB. You need to go into Dev Tools -> Application -> Clear Storage to do that. Then you should see that the database isn’t populated when you run ionic serve.


#5

Hi @nolanlawson, yes that’s exactly what I was doing. I incorrectly used the terminology ‘cache’ before.

The steps I followed were:

  1. Launch the application using ionic serve, then view the “Dev Tools -> Application” tab to confirm data is present:

  2. Select the “Dev Tools -> PouchDB” tab to confirm the data is in PouchDB:

  3. Delete the DB data by selecting “Dev Tools -> Application -> Clear Storage”:

  4. Confirm there is no longer a PouchDB database present on the “Dev Tools -> PouchDB” tab:

  5. Cancel (Ctrl + C) the original ionic serve command and re-launch ionic serve.

  6. Observe that the “Dev Tools -> Application” tab shows an instance of the PouchDB database, however no data is displayed within the application.

  7. Observe that the “Dev Tools -> PouchDB” tab shows an instance of the PouchDB database, however doesn’t indicate that any documents exist.

  8. Observe that when open the database in the “Dev Tools -> PouchDB” tab then it displays the correct documents.


#6

Thank you for the detailed explanation. Unfortunately I still don’t really know what’s going on. It’s possible that the PouchDB inspector is reporting old/invalid data. You can see the updated view of the IndexedDB data in Chrome’s IndexedDB explorer and right-clicking to do “refresh IndexedDB.”

I also don’t quite understand how you are populating data into the database or how this setup differs between Chrome and your app. If you need to refresh to fix it, then my guess is that this is a coding error on your part.

My guess is that your code isn’t listening for changes on the database, and is instead only showing the current state of the database (which is unloaded the first ttime you load your page). That’s why a refresh would fix it. You need to listen for chnages on the PouchDB database and ensure that you update your view when the data changes; I wrote a guide explaining how to do that: https://pouchdb.com/2015/02/28/efficiently-managing-ui-state-in-pouchdb.html

If you are still stuck, then I recommend hopping into the PouchDB slack channel and asking for help; usually someone there can provide live guidance! http://slack.pouchdb.com/


#7

Hi @nolanlawson,

After much frustration I think I have diagnosed what the problem is, however I’m not sure how to avoid it happening in the future. The problem appears to be a database issue and not an issue with my code. I managed to determine this by creating a completely new Cloudant DB, copying the documents form my Old DB over to my New DB and then pointing my app at the New DB.

It wasn’t until I did this that I noticed a difference in the databases listed on Cloudant:

As you will notice, the Old DB (grocery_db) has an information / alert telling me that “This database has just 8 docs and 83 deleted docs”. I initially thought that this wasn’t exactly a big deal, however I noticed that the New DB didn’t have this warning, and the results of the New DB are displayed within the GroceryApp after the “Clear Storage” command has been run in Dev Tools.

How did the OldDB get this warning? I’m not sure. During development I was creating and deleting multiple documents to test functionality, so somehow it must have happened then. I noticed that Cloudant doesn’t have the “Compact & Clean” functionality that PouchDB has, so the only way I can get rid of these deleted documents (or Tombstone docs as Cloudant refers to them) was to create a new database.

So, I believe that I have discovered the root of the problem, however I still have many questions:

  • What caused this “warning” to occur in Cloudant and why is it a problem?
  • Is there a way to prevent Cloudant from doing this again?
  • Why does my APp not load data from a database with this warning in Cloudant after the “Clear Storage” command has been run in Dev Tools? Is there a workaround for this that needs to be included in my app source code or PouchDB source code?

I’m going to keep an eye on my Cloudant databases to see if this happens to the New DB.

Thanks for all your help to date @nolanlawson!


#8

When you “delete” documents in Couch/Pouch/Cloudant it just creates a “tombstone.” So a database with 80 deleted docs still contains 80 tombstones that need to be replicated. This is a fundamental part of how the replication protocol is designed, because without it deletions wouldn’t replicate.

I’m still not sure exactly what’s going on in your scenario or what the problem is. If you’re ever unsure exactly what your database does or does not contain, you can use a tool like https://github.com/nolanlawson/pouchdb-dump-cli to dump the entire contents of a Couch/Cloudant database into a string, which you can then inspect yourself to see what’s inside (including deleted docs). You should also be aware that “clear storage” in Chrome dev tools will just erase your PouchDB database but won’t communicate the changes back to Cloudant. Hope that helps!


#9

Hey @UrbanCondor,
Im experiencing a similar problem with my setup, and just wondering if you ever got to the bottom of it? It sounded like there was probably something going wrong with your code. Sounds similar to mine.
Basically, the data is being synced in from my CloudDB server, and getting into the PouchDB in my ionic2 project, but isnt being show in the interface… unless I wait around for a while on the homepage before accessing the data page! Thats not practical of course, so I guess I need to either write some sort of interstitial loading screen while the sync is finishing, or figure out some refresh method, or else find the reason why the data doesnt just start populating as its being pulled down from the remote server.

Its probably my code thats at fault, but it would be nice to hear any insights you figured out along the way.
cheers


#10

I had a similar problem once and putting the data update into ngZone.run(() => ...) helped. See here for an example:


#11

Hi @eazyweb! Unfortunately I ended up abandoning the use of PouchDB due to this problem. I figured that if nolan couldn’t assist then there must be something seriously wrong! As a result I was forced to go in a different direction with my project. Sorry I can’t be much help, but good luck and let me know if you find a solution!


#12

My solution was that before loading the actual page, First load data or initialize the pouchdb in a dummy page…


#13

I have an issue but in my case Data loaded in Browser but when I am going to run app on device that time pouch data is not loaded and showing Failed to load resource: the server responded with a status of 404 (Object Not Found)
The above 404 is totally normal. PouchDB is just checking if a remote checkpoint exists.

Please Let me know the Issue Thanks


#14

Finally we solved the issue…The reason is you are trying to get the data before it’s finishing sync or replicate.You have to wait for sync or replication completion after that only you need to call the functions to get the data.We handled this case showing loading symbol while syncing and replicating when it’s done.We are trying to call the functions.

I have contributed this to github. it may help someone…