Syncing the Local PouchDB with the Remote Cloudant Database

auth0 pouchdb cloudant final app ionic

In this tutorial we are finally going to sync PouchDB with Cloudant in our database-per-user architecture. Up to this point we have setup a local PouchDB that is just set to “Tutorial.” We need to change this so that each PouchDB belongs to a specific user. When we setup our Authentication Service we pulled the user’s profile and we will be using the username part of their email address to setup a unique local database. We also setup similar rules when we provisioned their remote Cloudant Database which was based off of their username part of their email address and concatenated a hash to make sure we get unique databases.

Lets plug the local database and remote database together. We are going to start by making changes to the “pouch-db-service.”

This is the last and final code update to the pouch-db-service.ts. Here are some notable changes we need to go over.


this.remoteDatabase = `https://${profile.couchDB.key}:${profile.couchDB.password}@YOUR_CLOUDANT_HOST/${profile.couchDB.name}`;

Remember when we executed “configureForUser(profile)” and passed in the profile? We were just passing in “Tutorial.” When we are done with this tutorial we will be passing in the users profile which contains that CouchDB object. It contains their credentials which is their key, password and database name. The way you access a user’s database is with this pattern:

 https://USER_KEY:USER_PASSWORD@YOUR_CLOUDANT_HOST/USER_DB_NAME

cloudant database

The above image is a screenshot of the a user database are trying to sync to. You can see similar information about their database in Auth0 when you go to “Users” and choose a user. Their “app_metadata” will show the CouchDB object.

Just to be clear, “YOUR_CLOUDANT_HOST” is the same host name we got from your Cloudant Credentials. It’ll look like “some-hash-bluemix.cloudant.com.”

Next, we added 2 new functions which are autoSync() and sync(). This is just to demonstrate that you can manually sync the databases. You might have a use case for this. If you turn on autoSync, their will be continuous replication. The downside is that there will be a lot of API calls which was more of an issue before the “Lite” plan which does not chanrge per API call.

We will setup 2 buttons on the home screen where we can switch to autoSync instead of manually sync.

Here is the full code with the changes we discussed above. I didn’t go over every detail as there are comments in the code for your review.

Next we are going to update the Home.ts file for the 3rd time. The changes aren’t too significant. We are going to add 2 methods that work with the pouch-db-service which are autoSync() and syncData(). There is a lot going on in the comments for syncData. Most of it is to demonstrate that the syncing is happening.

In the Home.ts constructor we removed the fixed database naming. Now we are going to check if the user is authenticated. They really shouldn’t be able to get this far without being authenticated anyway. If they are, we are going to get their profile information for configuration of their databases. Then we are going to load their friends. If they are not authenticated then the friends array will just be empty.


if (this.auth.authenticated()) {

this.auth.getUserProfile().then(profile => {

this.pouchdbService.configureForUser(profile);
this.loadFriends();

});

} else {
this.friends = [];
}

Lastly, we need to update the view to add the sync buttons. The changes are at the bottom which are 2 buttons to sync. Once you turn on Auto Sync, you can’t go back to manual in this start example.

Here is the full code for the home view.

Before we can sync we need to log back into IBM Bluemix and enable Cross-Origin Resource Sharing (CORS). Go to your Cloudant database > Account and go to the CORS tab and choose “All Domains.” If you don’t do this then they won’t sync.

cloudant enable cors

One last image showing that the 2 databases sync.

cloudant pouchdb sync

That’s all! I hope this worked for you. Let me know if you have any issues or questions in the comments.

This is the final project on GitHub.