{"id":3553,"date":"2017-05-10T05:21:49","date_gmt":"2017-05-10T12:21:49","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=3553"},"modified":"2025-06-13T19:58:32","modified_gmt":"2025-06-14T02:58:32","slug":"fakeit-series-5-5-rapid-mobile-development-sync-gateway","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/","title":{"rendered":"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway"},"content":{"rendered":"<p><a href=\"https:\/\/twitter.com\/bentonam\">Aaron Benton<\/a> is an experienced architect who specializes in creative solutions to develop innovative mobile applications. He has over 10 years experience in full stack development, including ColdFusion, SQL, NoSQL, JavaScript, HTML, and CSS. Aaron is currently an Applications Architect for Shop.com in Greensboro, North Carolina and is a <a href=\"https:\/\/developer.couchbase.com\/experts-and-champions\">Couchbase Community Champion<\/a>.<\/p>\n<p class=\"no-underline\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2974\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/03\/aaronb-benton-headshot_1000x1000-300x300.jpg\" alt=\"Aaron Benton\" width=\"300\" height=\"300\" data-attachment-id=\"2974\" data-permalink=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-generating-fake-data\/aaronb-benton-headshot_1000x1000\/\" data-orig-file=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/03\/aaronb-benton-headshot_1000x1000.jpg\" data-orig-size=\"1000,1000\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"\" data-image-description=\"\" data-medium-file=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/03\/aaronb-benton-headshot_1000x1000-300x300.jpg\" data-large-file=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/03\/aaronb-benton-headshot_1000x1000.jpg\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000-300x300.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000-150x150.jpg 150w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000-768x768.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000-65x65.jpg 65w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000-50x50.jpg 50w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000-20x20.jpg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000.jpg 1000w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>For our last post in the <u><a href=\"https:\/\/github.com\/bentonam\/fakeit\" target=\"_blank\" rel=\"noopener\">FakeIt<\/a><\/u>\u00a0series we are going to explore how we can leverage <u><a href=\"https:\/\/github.com\/bentonam\/fakeit\" target=\"_blank\" rel=\"noopener\">FakeIt<\/a><\/u>\u00a0+ <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-server\/\" target=\"_blank\" rel=\"noopener\">Couchbase Server<\/a><\/u>\u00a0+ <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-mobile\/\" target=\"_blank\" rel=\"noopener\">Sync Gateway<\/a><\/u>\u00a0to get our local environment up and running for mobile development. We will be doing this by using <u><a href=\"https:\/\/www.docker.com\/\" target=\"_blank\" rel=\"noopener\">Docker<\/a><\/u>\u00a0and <u><a href=\"https:\/\/docs.docker.com\/compose\/\" target=\"_blank\" rel=\"noopener\">docker-compose<\/a><\/u>. <em>Disclaimer: I am by no means a Docker expert, this is simply an example of what I&#8217;ve done to quickly setup a development environment and dataset.<\/em><\/p>\n<h3><strong>Docker<\/strong><\/h3>\n<p>We will be using two Docker Containers, one for <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-server\/\" target=\"_blank\" rel=\"noopener\">Couchbase Server<\/a><\/u>\u00a0and one for <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-mobile\/\" target=\"_blank\" rel=\"noopener\">Sync Gateway<\/a><\/u>. We could define a docker-compose.yaml\u00a0file that simply pulled from couchbase:latest\u00a0and couchbase\/sync-gateway:latest\u00a0but there would still be a need for manual configuration and we want to be able to automate as much as possible for our application. To do that we will need to build our own containers from both of these adding our own scripts and configuration.<\/p>\n<pre class=\"lang:default decode:true \">.\/docker-compose.yaml\r\n\r\nversion:\u00a0'2'\r\nservices:\r\n\u00a0 fakeit-couchbase:\r\n\u00a0 \u00a0 build:\r\n\u00a0 \u00a0 \u00a0 context:\u00a0.\/.docker\/couchbase\/\r\n\u00a0 \u00a0 container_name:\u00a0fakeit-couchbase\r\n\u00a0 \u00a0 ports:\r\n\u00a0 \u00a0 \u00a0 -\u00a0\"8091-8094:8091-8094\"\r\n\u00a0 \u00a0 \u00a0 -\u00a0\"11210:11210\"\r\n\u00a0 \u00a0 volumes:\r\n\u00a0 \u00a0 \u00a0 -\u00a0.\/:\/app\r\n\u00a0 fakeit-syncgatway:\r\n\u00a0 \u00a0 build:\r\n\u00a0 \u00a0 \u00a0 context:\u00a0.\/.docker\/sync-gateway\/\r\n\u00a0 \u00a0 container_name:\u00a0fakeit-syncgateway\r\n\u00a0 \u00a0 depends_on:\r\n\u00a0 \u00a0 \u00a0 -\u00a0fakeit-couchbase\r\n\u00a0 \u00a0 ports:\r\n\u00a0 \u00a0 \u00a0 -\u00a0\"4984-4985:4984-4985\"\r\n\u00a0 \u00a0 volumes:\r\n\u00a0 \u00a0 \u00a0 -\u00a0.\/:\/app<\/pre>\n<p>Our docker-compose.yaml\u00a0file is first building a container in the Dockerfile from .\/.docker\/couchbase\/Dockerfile\u00a0which looks like this.<\/p>\n<pre class=\"lang:default decode:true \">.\/.docker\/couchbase\/Dockerfile\r\n\r\n# start with couchbase\r\nFROM\u00a0couchbase:latest\r\n\r\n# copy the configure script\r\nCOPY\u00a0scripts\/configure-node.sh \/opt\/couchbase\r\n\r\n# execute the configure-node.sh script \r\nCMD [\"\/opt\/couchbase\/configure-node.sh\"]\r\n\r\n<\/pre>\n<p>This Dockerfile\u00a0is really only doing two things, copying a configuration script and executing that script. The configure-node.sh\u00a0script looks like this.<\/p>\n<pre class=\"lang:default decode:true\">.\/.docker\/couchbase\/scripts\/configure-node.sh\r\n\r\nset\u00a0-m\r\n\r\n\/entrypoint.sh couchbase-server &amp;\r\n\r\necho\u00a0'Waiting 20 seconds for Couchbase service to start'\r\nsleep 20\r\n\r\n# configure the cluster\r\necho\u00a0'Configuring Cluster'\r\n\/opt\/couchbase\/bin\/couchbase-cli cluster-init -c localhost:8091 --cluster-username=Administrator --cluster-password=password --cluster-port=8091 --cluster-ramsize=500 --service=data\r\n\r\n# create the ecommerce bucket\r\necho\u00a0'Creating ecommerce bucket'\r\n\/opt\/couchbase\/bin\/couchbase-cli bucket-create -c localhost:8091 -u Administrator -p password --bucket=ecommerce --bucket-eviction-policy=fullEviction --bucket-type=membase --bucket-priority=high --enable-index-replica=0 --bucket-port=11211 --enable-flush=1 --bucket-replica=1 --bucket-ramsize=200\r\n\r\necho\u00a0'Couchbase server is ready'\r\n\r\nfg\u00a01\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>The configure-node.sh\u00a0script is doing a couple of things:<\/p>\n<ol>\n<li>Waiting for the Couchbase service to start so it can be configured<\/li>\n<li>Initializing the Cluster configuration<\/li>\n<li>Creating our ecommerce\u00a0bucket<\/li>\n<\/ol>\n<p>The Couchbase container is now built, the next container that needs to be built is the Sync Gateway container. By default the Sync Gateway container uses the walrus\u00a0memory only sync gateway bucket. We will need to update this configuration by providing our own sync-gateway.json\u00a0file so we can update the storage and access settings. Lastly, the Sync Gateway container only exposes port 4984, which is the public port, as this is for development purposes we will go ahead and expose port 4985 which is the administrator port.<\/p>\n<pre class=\"lang:default decode:true \">.\/.docker\/sync-gateway\/Dockerfile\r\n\r\n# Start with the base sync gateway\r\nFROM\u00a0couchbase\/sync-gateway:latest\r\n\r\n# Copy the sync-gateway.json into the container\r\nCOPY\u00a0sync-gateway.json \/opt\/sync_gateway\/sync-gateway.json\r\n\r\n# Create Volume for data to persist\r\nRUN mkdir -p \/opt\/sync_gateway\/data\r\n\r\n# Copy Entry Point\r\nCOPY scripts\/entrypoint.sh \/\r\nENTRYPOINT [\"\/entrypoint.sh\"]\r\n\r\n# Copy the configure script\r\nCOPY scripts\/configure-node.sh \/opt\/sync_gateway\r\n\r\n# Configure the Sync Gateway and Start it\r\nCMD [\"\/opt\/sync_gateway\/configure-node.sh\"]\r\n\r\n# \u00a0port 4984: public port\r\n# \u00a0port 4985: admin port\r\nEXPOSE 4984 4985\r\n\r\n.\/.docker\/sync-gateway\/sync-gateway.json\r\n\r\n{\r\n\u00a0\"interface\": \"0.0.0.0:4984\",\r\n\u00a0\"adminInterface\": \"0.0.0.0:4985\",\r\n\u00a0\"log\": [\"CRUD+\", \"REST+\", \"Changes+\", \"Attach+\"],\r\n\u00a0\"CORS\": {\r\n\u00a0 \u00a0\"Origin\":[\r\n\u00a0 \u00a0\u00a0 \"https:\/\/localhost:8000\",\r\n\u00a0 \u00a0 \"*\"\r\n\u00a0 \u00a0 ],\r\n\u00a0 \u00a0\"LoginOrigin\":[\r\n\u00a0 \u00a0 \u00a0\"https:\/\/localhost:8000\",\r\n\u00a0 \u00a0 \u00a0\"*\"\r\n\u00a0 \u00a0],\r\n\u00a0 \u00a0\"Headers\":[\"Content-Type\"],\r\n\u00a0 \u00a0\"MaxAge\": 1728000\r\n\u00a0},\r\n\u00a0\"databases\": {\r\n\u00a0 \u00a0\"ecommerce\": {\r\n\u00a0 \u00a0 \u00a0\"server\": \"https:\/\/fakeit-couchbase:8091\",\r\n\u00a0 \u00a0 \u00a0\"bucket\": \"ecommerce\",\r\n\u00a0 \u00a0 \u00a0\"users\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0\"GUEST\": {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0\"disabled\": false\r\n\u00a0 \u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0 \u00a0},\r\n\u00a0 \u00a0 \u00a0\"sync\": \"function(doc, oldDoc) { channel(doc.channels); }\"\r\n\u00a0 \u00a0}\r\n\u00a0}\r\n}\r\n\r\n.\/.docker\/sync-gateway\/scripts\/configure-node.sh\r\n\r\n#!\/bin\/bash\r\n\r\nset\u00a0-m\r\n\r\necho\u00a0'Waiting 20 seconds for Couchbase service to start and warm up'\r\n\r\nsleep 20\r\n\r\necho\u00a0'Starting the Sync Gateway Service'\r\n\/entrypoint.sh sync_gateway \/opt\/sync_gateway\/sync-gateway.json\r\n\r\necho\u00a0'Couchbase Sync Gateway is ready'<\/pre>\n<p>&nbsp;<\/p>\n<p>Again, this is for development purposes only. You should never allow access from anywhere to your adminInterface\u00a0or enable <strong>GUEST<\/strong>\u00a0access to your sync-gateway unless there is a very good reason to do so.<\/p>\n<p>The structure of our app now looks like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/05\/app-structure.jpg\" alt=\"app structure\" \/><\/p>\n<p>Now that we have configured out Docker containers and setup our docker-compose.yaml file we need to build and start the containers. We do this by executing the following command from within our applications directory:<\/p>\n<pre class=\"lang:default decode:true \">docker-compose up -d\r\n\r\n<\/pre>\n<p><em>Note:<\/em>\u00a0for the purposes of the screencast, the -d\u00a0parameter to run the containers in detached mode is omitted.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5677 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/05\/blog5-example1-compressor.gif\" alt=\"\" width=\"800\" height=\"443\" \/><\/p>\n<h3><strong>Models<\/strong><\/h3>\n<p>Our containers are now started, the next thing we need to do before we generate our dataset is update the models to support the channels attribute.<\/p>\n<pre class=\"lang:default decode:true\">users.yaml\r\n\r\n<\/pre>\n<p>This model will only be synced to user specific channels.<\/p>\n<pre class=\"lang:default decode:true \">name:\u00a0Users\r\ntype:\u00a0object\r\nkey:\u00a0_id\r\ndata:\r\n\u00a0 min:\u00a01000\r\n\u00a0 max:\u00a02000\r\n\u00a0 inputs:\u00a0.\/countries.json\r\nproperties:\r\n\u00a0 _id:\r\n\u00a0 \u00a0 type:\u00a0string\r\n\u00a0 \u00a0 description:\u00a0The document id built by the prefix \"user_\"\u00a0and the users id\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 post_build:\u00a0`user_${this.user_id}`\r\n\u00a0 channels:\r\n\u00a0 \u00a0 type:\u00a0array\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 post_build:\u00a0|\r\n\u00a0 \u00a0 \u00a0 \u00a0return [ `channel-user-${this.user_id}` ];\r\n\u00a0 doc_type:\r\n\u00a0 \u00a0 type:\u00a0string\r\n\u00a0 \u00a0 description:\u00a0The document type\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 value:\u00a0\"user\"\r\n...\r\n\r\nproducts.yaml<\/pre>\n<p>Just for fun we will publish this model to a global channel all of our users will be subscribed to.<\/p>\n<pre class=\"lang:default decode:true \">name:\u00a0Products\r\ntype:\u00a0object\r\nkey:\u00a0_id\r\ndata:\r\n\u00a0 min:\u00a0500\r\n\u00a0 max:\u00a01000\r\n\u00a0 inputs:\r\n\u00a0 \u00a0 -\u00a0.\/categories.csv\r\n\u00a0 pre_build:\u00a0globals.current_category = faker.random.arrayElement(inputs.categories);\r\nproperties:\r\n\u00a0 _id:\r\n\u00a0 \u00a0 type:\u00a0string\r\n\u00a0 \u00a0 description:\u00a0The document id\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 post_build:\u00a0`product_${this.product_id}`\r\n\u00a0 channels:\r\n\u00a0 \u00a0 type:\u00a0array\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 build:\u00a0|\r\n\u00a0 \u00a0 \u00a0 \u00a0return [ `channel-products` ];\r\n\u00a0 doc_type:\r\n\u00a0 \u00a0 type:\u00a0string\r\n\u00a0 \u00a0 description:\u00a0The document type\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 value:\u00a0product\r\n...\r\n\r\norders.yaml<\/pre>\n<p>This model will only be synced to user specific channels.<\/p>\n<pre class=\"lang:default decode:true \">name:\u00a0Orders\r\ntype:\u00a0object\r\nkey:\u00a0_id\r\ndata:\r\n\u00a0 dependencies:\r\n\u00a0 \u00a0 -\u00a0products.yaml\r\n\u00a0 \u00a0 -\u00a0users.yaml\r\n\u00a0 min:\u00a05000\r\n\u00a0 max:\u00a06000\r\nproperties:\r\n\u00a0 _id:\r\n\u00a0 \u00a0 type:\u00a0string\r\n\u00a0 \u00a0 description:\u00a0The document id\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 post_build:\u00a0`order_${this.order_id}`\r\n\u00a0 channels:\r\n\u00a0 \u00a0 type:\u00a0array\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 build:\u00a0|\r\n\u00a0 \u00a0 \u00a0 \u00a0return [ `channel-user-${this.user_id}` ];\r\n\u00a0 doc_type:\r\n\u00a0 \u00a0 type:\u00a0string\r\n\u00a0 \u00a0 description:\u00a0The document type\r\n\u00a0 \u00a0 data:\r\n\u00a0 \u00a0 \u00a0 value:\u00a0\"order\"\r\n...\r\n\r\n<\/pre>\n<p>Now that our models have been updated to support channels, we can generate our random dataset and push it into <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-server\/\" target=\"_blank\" rel=\"noopener\">Couchbase Server<\/a><\/u>\u00a0through the <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-mobile\/\" target=\"_blank\" rel=\"noopener\">Sync Gateway<\/a><\/u>\u00a0REST API. We tell <u><a href=\"https:\/\/github.com\/bentonam\/fakeit\" target=\"_blank\" rel=\"noopener\">FakeIt<\/a><\/u>\u00a0to do this by using the following command:<\/p>\n<pre class=\"lang:default decode:true \">fakeit sync-gateway --server https:\/\/localhost:4984 --bucket ecommerce --verbose models\/*\r\n\r\n<\/pre>\n<p>For development purposes we have allowed guest access to our <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-mobile\/\" target=\"_blank\" rel=\"noopener\">Sync Gateway<\/a><\/u>. However, if you have guest access disabled, you can still use <u><a href=\"https:\/\/github.com\/bentonam\/fakeit\" target=\"_blank\" rel=\"noopener\">FakeIt<\/a><\/u>\u00a0by specifying a username and password to an existing user by using the following command:<\/p>\n<pre class=\"lang:default decode:true \">fakeit sync-gateway --server https:\/\/localhost:4984 --bucket ecommerce --username YOURUSERNAME --password YOURPASSWORD --verbose models\/*<\/pre>\n<p>Before the generated dataset is output, <u><a href=\"https:\/\/github.com\/bentonam\/fakeit\" target=\"_blank\" rel=\"noopener\">FakeIt<\/a><\/u>\u00a0will authenticate against the <u><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/couchbase-mobile\/\" target=\"_blank\" rel=\"noopener\">Sync Gateway<\/a><\/u>\u00a0to retrieve the necessary session information.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5673 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/05\/blog5-example2-compressor.gif\" alt=\"\" width=\"800\" height=\"450\" \/><\/p>\n<h3><strong>Testing<\/strong><\/h3>\n<p>The next thing we need to do is to create a sync gateway user so that we can sync their documents locally. For this test, we are going to grab a random user document from our Users model and create a user from that document. In this example it will be user_1001, and we will create the user using the curl command:<\/p>\n<pre class=\"lang:default decode:true \">curl --silent --show-error \\\r\n\u00a0-H \"Content-Type: application\/json; charset=UTF-8\"\u00a0\\\r\n\u00a0-H \"Content-type: application\/json\"\u00a0\\\r\n\u00a0-X PUT \\\r\n\u00a0-d '{\"name\":\"Domenic81\",\"password\":\"pgid_Tubn0qoEtZ\",\"admin_channels\":[\"channel-user-1001\", \"channel-products\"]}'\u00a0\\\r\n\u00a0'https:\/\/localhost:4985\/ecommerce\/_user\/Domenic81'<\/pre>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/05\/blog5-example3.gif\" alt=\"blog5 example3\" \/><\/p>\n<h3><strong>Application<\/strong><\/h3>\n<p>We&#8217;ve created a small <u><a href=\"https:\/\/vuejs.org\/\" target=\"_blank\" rel=\"noopener\">VueJS<\/a><\/u>\u00a0project that utilizes <u><a href=\"https:\/\/pouchdb.com\/\" target=\"_blank\" rel=\"noopener\">PouchDB<\/a><\/u>\u00a0to connect to the Sync Gateway and pull an authenticated users documents. Our application is going to just show the different types of documents available, their IDs and content.<\/p>\n<pre class=\"lang:default decode:true \">\/\/ register highlight.js vue component\r\nVue.use(VueHighlightJS)\r\n\r\n\/\/ create local ecommerce database\r\nvar\u00a0db = new\u00a0PouchDB('local_ecommerce', {\r\n\u00a0auto_compaction: true,\r\n\u00a0revs_limit: 3\r\n});\r\n\/\/ create remote ecommerce database\r\nvar\u00a0remote_db = new\u00a0PouchDB('https:\/\/localhost:4984\/ecommerce\/', {\r\n\u00a0auth: {\r\n\u00a0 \u00a0username: 'Domenic81',\r\n\u00a0 \u00a0password: 'pgid_Tubn0qoEtZ'\r\n\u00a0},\r\n\u00a0skip_setup: true\r\n});\r\n\/\/ merge remote database with local database\r\nPouchDB.sync(db, remote_db, { live: true, retry: true\u00a0})\r\n\r\nvar\u00a0app = new\u00a0Vue({\r\n\u00a0el: '#app',\r\n\u00a0data: {\r\n\u00a0 \u00a0current_type: '',\r\n\u00a0 \u00a0items: [],\r\n\u00a0 \u00a0id: '',\r\n\u00a0 \u00a0current: JSON.stringify({}),\r\n\u00a0 \u00a0types: [],\r\n\u00a0},\r\n\u00a0watch: {\r\n\u00a0 \u00a0id(id) {\r\n\u00a0 \u00a0 \u00a0if\u00a0(id) {\r\n\u00a0 \u00a0 \u00a0 \u00a0db.get(id).then((current) =&gt; this.current = JSON.stringify(current, null, 2))\r\n\u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0},\r\n\u00a0 \u00a0current_type(type) {\r\n\u00a0 \u00a0 \u00a0this.id = ''\r\n\u00a0 \u00a0 \u00a0\/\/ update the current item to be blank\r\n\u00a0 \u00a0 \u00a0this.current = JSON.stringify({})\r\n\r\n\u00a0 \u00a0 \u00a0\/\/ when `current_type` changes update the items list with the current types list\r\n\u00a0 \u00a0 \u00a0this.updateItems(type)\r\n\u00a0 \u00a0 \u00a0 \u00a0.then(() =&gt; {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0if\u00a0(!this.id) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this.id = this.items[0]\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0 \u00a0 \u00a0})\r\n\u00a0 \u00a0}\r\n\u00a0},\r\n\u00a0methods: {\r\n\u00a0 \u00a0updateItems(type) {\r\n\u00a0 \u00a0 \u00a0return\u00a0db.query('ecommerce\/by_doc_type', { key: type, reduce: false\u00a0})\r\n\u00a0 \u00a0 \u00a0 \u00a0.then((result) =&gt; {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0this.items = result.rows.map((item) =&gt; item.id)\r\n\u00a0 \u00a0 \u00a0 \u00a0})\r\n\u00a0 \u00a0},\r\n\u00a0 \u00a0removeStyle(el) {\r\n\u00a0 \u00a0 \u00a0setTimeout(() =&gt; {\r\n\u00a0 \u00a0 \u00a0 \u00a0el.style = ''\r\n\u00a0 \u00a0 \u00a0}, 1000)\r\n\u00a0 \u00a0}\r\n\u00a0},\r\n\u00a0created() {\r\n\u00a0 \u00a0\/\/ create the view to be queried\r\n\u00a0 \u00a0var\u00a0ddoc = {\r\n\u00a0 \u00a0 \u00a0_id: '_design\/ecommerce',\r\n\u00a0 \u00a0 \u00a0views: {\r\n\u00a0 \u00a0 \u00a0 \u00a0by_doc_type: {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0map: function(doc) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0if\u00a0(doc.doc_type) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0emit(doc.doc_type);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0}.toString(),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0reduce: '_count'\r\n\u00a0 \u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0}\r\n\r\n\u00a0 \u00a0db.put(ddoc)\r\n\u00a0 \u00a0 \u00a0\/\/ design document created\r\n\u00a0 \u00a0 \u00a0\/\/ call the design document view index immediately to trigger a build\r\n\u00a0 \u00a0 \u00a0.then(() =&gt; db.query('ecommerce\/by_doc_type', { limit: 0\u00a0}))\r\n\u00a0 \u00a0 \u00a0.catch((err) =&gt; { \/\/ it is fine if this fails and returns a document conflict that just means it doesnt need to be created\r\n\u00a0 \u00a0 \u00a0 \u00a0if\u00a0(err.status !== 409) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0throw\u00a0err;\r\n\u00a0 \u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0 \u00a0})\r\n\r\n\u00a0 \u00a0 \u00a0\/\/ get all of the doc types available\r\n\u00a0 \u00a0 \u00a0.then(() =&gt; db.query('ecommerce\/by_doc_type', { reduce: true, group: true\u00a0}))\r\n\u00a0 \u00a0 \u00a0.then((types) =&gt; {\r\n\u00a0 \u00a0 \u00a0 \u00a0this.types = types.rows.map((type) =&gt; type.key)\r\n\u00a0 \u00a0 \u00a0 \u00a0this.current_type = this.types[0]\r\n\u00a0 \u00a0 \u00a0})\r\n\u00a0}\r\n})<\/pre>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5675 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/05\/blog5-example4-compressor.gif\" alt=\"\" width=\"800\" height=\"505\" \/><\/p>\n<p>The entire sample application can be viewed at <u><a href=\"https:\/\/github.com\/bentonam\/fakeit-couchbase-mobile-example\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/bentonam\/fakeit-couchbase-mobile-example<\/a><\/u><\/p>\n<h3><strong>Conclusion<\/strong><\/h3>\n<p>Throughout this series you&#8217;ve seen how <u><a href=\"https:\/\/github.com\/bentonam\/fakeit\" target=\"_blank\" rel=\"noopener\">FakeIt<\/a><\/u>\u00a0can take simple YAML models and generate vast amounts of fake data and send that data to multiple different destinations. Please checkout the repository, pull requests are welcome, we are always looking for improvements and enhancements to make the tool more useful for the community. I would also like to take this time to thank those who&#8217;ve made contributions to the project. The 1.0 version would not have been released without the help of \u00a0<u><a href=\"https:\/\/github.com\/tjbenton\" target=\"_blank\" rel=\"noopener\">Tyler Benton<\/a><\/u>\u00a0(<u><a href=\"https:\/\/twitter.com\/tjbenton21\" target=\"_blank\" rel=\"noopener\">@tjbenton21<\/a><\/u>), also <u><a href=\"https:\/\/github.com\/tabrindle\" target=\"_blank\" rel=\"noopener\">Trevor Brindle<\/a><\/u>\u00a0(<u><a href=\"https:\/\/twitter.com\/VinceKerrazzi\" target=\"_blank\" rel=\"noopener\">@VinceKerrazzi<\/a><\/u>), <u><a href=\"https:\/\/github.com\/mistersender\" target=\"_blank\" rel=\"noopener\">Jessica Kennedy<\/a><\/u>\u00a0(<u><a href=\"https:\/\/twitter.com\/mistersender\" target=\"_blank\" rel=\"noopener\">@mistersender<\/a><\/u>), <u><a href=\"https:\/\/github.com\/alburdette619\" target=\"_blank\" rel=\"noopener\">Adam Burdette<\/a><\/u>\u00a0(<u><a href=\"https:\/\/twitter.com\/RavenStorms619\" target=\"_blank\" rel=\"noopener\">@RavenStorms619<\/a><\/u>) and <u><a href=\"https:\/\/github.com\/brantburnett\" target=\"_blank\" rel=\"noopener\">Brant Burnett<\/a><\/u>\u00a0(<u><a href=\"https:\/\/twitter.com\/btburnett3\" target=\"_blank\" rel=\"noopener\">@btburnett3<\/a><\/u>)<\/p>\n<h4><strong>Previous<\/strong><\/h4>\n<ul>\n<li><u><a href=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-generating-fake-data\/\" target=\"_blank\" rel=\"noopener\">FakeIt Series 1 of 5: Generating Fake Data<\/a><\/u><\/li>\n<li><u><a href=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-shared-data-dependencies\/\" target=\"_blank\" rel=\"noopener\">FakeIt Series 2 of 5: Shared Data and Dependencies<\/a><\/u><\/li>\n<li><u><a href=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-3-5-lean-models-through-definitions\/\" target=\"_blank\" rel=\"noopener\">FakeIt Series 3 of 5: Lean Models through Definitions<\/a><\/u><\/li>\n<li><u><a href=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-working-existing-data\/\" target=\"_blank\" rel=\"noopener\">FakeIt Series 4 of 5: Working with Existing Data<\/a><\/u><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-2966 aligncenter\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/03\/brand.devCommChampionLogo.champion.FINAL_-300x300.png\" alt=\"Couchbase Champion\" width=\"300\" height=\"300\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How we can leverage FakeIt + Couchbase Server + Sync Gateway to get our local environment up and running for mobile development. We will be doing this by using Docker and docker-compose. <\/p>\n","protected":false},"author":53,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1810,1816,2366],"tags":[1883,1519,1884],"ppma_author":[9026],"class_list":["post-3553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile","category-couchbase-server","category-sync-gateway","tag-data-modelling","tag-docker","tag-document-patterns"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>FakeIt Series: Rapid Mobile Development with Sync-Gateway<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway\" \/>\n<meta property=\"og:description\" content=\"How we can leverage FakeIt + Couchbase Server + Sync Gateway to get our local environment up and running for mobile development. We will be doing this by using Docker and docker-compose.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-05-10T12:21:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T02:58:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"1000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway\",\"datePublished\":\"2017-05-10T12:21:49+00:00\",\"dateModified\":\"2025-06-14T02:58:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\"},\"wordCount\":879,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"data modelling\",\"docker\",\"document patterns\"],\"articleSection\":[\"Couchbase Mobile\",\"Couchbase Server\",\"Sync Gateway\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\",\"name\":\"FakeIt Series: Rapid Mobile Development with Sync-Gateway\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-05-10T12:21:49+00:00\",\"dateModified\":\"2025-06-14T02:58:32+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\",\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"caption\":\"Laura Czajkowski, Developer Community Manager, Couchbase\"},\"description\":\"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"FakeIt Series: Rapid Mobile Development with Sync-Gateway","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/","og_locale":"en_US","og_type":"article","og_title":"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway","og_description":"How we can leverage FakeIt + Couchbase Server + Sync Gateway to get our local environment up and running for mobile development. We will be doing this by using Docker and docker-compose.","og_url":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-05-10T12:21:49+00:00","article_modified_time":"2025-06-14T02:58:32+00:00","og_image":[{"width":1000,"height":1000,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/03\/aaronb-benton-headshot_1000x1000.jpg","type":"image\/jpeg"}],"author":"Laura Czajkowski, Developer Community Manager, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Laura Czajkowski, Developer Community Manager, Couchbase","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway","datePublished":"2017-05-10T12:21:49+00:00","dateModified":"2025-06-14T02:58:32+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/"},"wordCount":879,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["data modelling","docker","document patterns"],"articleSection":["Couchbase Mobile","Couchbase Server","Sync Gateway"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/","url":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/","name":"FakeIt Series: Rapid Mobile Development with Sync-Gateway","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-05-10T12:21:49+00:00","dateModified":"2025-06-14T02:58:32+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/fakeit-series-5-5-rapid-mobile-development-sync-gateway\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"FakeIt Series 5 of 5: Rapid Mobile Development with Sync-Gateway"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220","name":"Laura Czajkowski, Developer Community Manager, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409","url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","caption":"Laura Czajkowski, Developer Community Manager, Couchbase"},"description":"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.","url":"https:\/\/www.couchbase.com\/blog\/author\/laura-czajkowski\/"}]}},"authors":[{"term_id":9026,"user_id":53,"is_guest":0,"slug":"laura-czajkowski","display_name":"Laura Czajkowski, Developer Community Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","author_category":"","last_name":"Czajkowski","first_name":"Laura","job_title":"","user_url":"","description":"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/3553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=3553"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/3553\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=3553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=3553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=3553"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=3553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}