{"id":302,"date":"2015-12-16T01:03:04","date_gmt":"2015-12-16T01:03:03","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\/"},"modified":"2015-12-16T01:03:04","modified_gmt":"2015-12-16T01:03:03","slug":"first-steps-with-pouchdb-sync-gateway-todomvc-todolite","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\/","title":{"rendered":"First steps with PouchDB &amp; Sync Gateway"},"content":{"rendered":"\n<p>This week, <a href=\"https:\/\/pouchdb.com\/2015\/04\/07\/better-late-than-never.html\">PouchDB v3.4.0<\/a>\u00a0was released with Couchbase Sync Gateway compatibility.<\/p>\n\n\n\n<p>In this post, we\u2019ll take the existing \ufffcTodoMVC example\ufffc and add filtered sync using Facebook authentication. In addition to syncing between Web clients, we\u2019ll change the data model slightly to sync with the existing ToDoLite apps running on <a href=\"https:\/\/github.com\/couchbaselabs\/ToDoLite-iOS\">iOS\ufffc<\/a> and <a href=\"https:\/\/github.com\/couchbaselabs\/ToDoLite-Android\">\ufffcAndroid<\/a>:<\/p>\n\n\n\n<p>To follow along, you can open and run the TodoMVC example at commit \ufffc<a href=\"https:\/\/github.com\/jamiltz\/getting-started-todo\/commit\/d9bb9612a611535898901feab9399610927fa9ed\">d9bb961<\/a>. For convenience, I\u2019ve added the Facebook login code in <strong>app.js<\/strong>. When the user logs in, the function <strong>startSessionAndSync(accessToken, userId)<\/strong>\u00a0is called. Now let\u2019s add the code to make it happen!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">QuickStart<\/h1>\n\n\n\n<p>Make sure to serve the app on port <strong>9000<\/strong>\u00a0as we will configure CORS for <strong>localhost:9000<\/strong>\u00a0later. The simple python command should do:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ python -m SimpleHTTPServer 9000\r\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Data modelling<\/h1>\n\n\n\n<p>TodoMVC and ToDoLite have a slightly different data model. In ToDoLite apps, a user can create multiple lists and share them with multiple users.<\/p>\n\n\n\n<p>First let\u2019s look at a Task document with the expected <strong>title<\/strong>\u00a0property and a <strong>list_id<\/strong>\u00a0referencing the List it belongs to (in this case 123):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\r\n  &quot;_id&quot;: &quot;E9W3-9I2Y-O8W2-6Y4D&quot;,\r\n  &quot;type&quot;: &quot;task&quot;,\r\n  &quot;list_id&quot;: &quot;123&quot;,\r\n  &quot;title&quot;: &quot;A task title&quot;\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>Likewise, a List document also has a <strong>title<\/strong>\u00a0and an owner referencing the user it belongs to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\r\n  &quot;_id&quot;: &quot;123&quot;,\r\n  &quot;type&quot;: &quot;list&quot;,\r\n  &quot;title&quot;: &quot;TodoMVC list&quot;,\r\n  &quot;owner&quot;: &quot;p:1234567890&quot;\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>TodoMVC however is a single list app. To keep things simple we can insert the List document in code as soon as the user logs in.<\/p>\n\n\n\n<p>Let\u2019s create a new function called <strong>migrateGuestToUser<\/strong> to create the List document with the user id and save it to PouchDB:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function migrateGuestToUser(userId) {\r\n  var list = {\r\n    _id: &#039;123&#039;,\r\n    type: &#039;list&#039;,\r\n    title: &#039;TodoMVC list&#039;,\r\n    owner: &#039;p:&#039; + userId\r\n  };\r\n  db.put(list, function(err, result) {\r\n    if (!err) {\r\n      console.log(&#039;Successfully saved user list&#039;);\r\n    }\r\n  })\r\n}\r\n<\/code><\/pre>\n\n\n\n<p><strong>Note:<\/strong> It\u2019s very important to set the owner field, the sync function will reject the document <a href=\"https:\/\/github.com\/jamiltz\/getting-started-todo\/blob\/master\/sync-gateway-config.json#L28\">otherwise<\/a>.<\/p>\n\n\n\n<p>And we can call it in <strong>startSessionAndSync<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function startSessionAndSync(accessToken, userId) {\r\n  migrateGuestToUser(userId);\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>Task documents belong to a list and so they have a <strong>list_id<\/strong> property we need to set. Change the <strong>addTodo<\/strong> function in <strong>app.js<\/strong> to look like below. Notice we set the <strong>list_id<\/strong> field to the hardcoded <strong>_id<\/strong> of the list we inserted above:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function addTodo(text) {\r\n  var todo = {\r\n    _id: new Date().toISOString(),\r\n    title: text,\r\n    checked: false,\r\n    type: &#039;task&#039;,\r\n    list_id: &#039;123&#039;,\r\n    created_at: new Date()\r\n  };\r\n  db.put(todo, function callback(err, result) {\r\n    if (!err) {\r\n      console.log(&#039;Successfully posted a todo!&#039;);\r\n    }\r\n  });\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>Now we have the appropriate documents conforming to ToDoLite\u2019s data model we can take a look at authentication and replication.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Enabling CORS on Sync Gateway<\/h1>\n\n\n\n<p>In this tutorial, we\u2019ll run a local instance of Sync Gateway on <strong>localhost:4984<\/strong> but we\u2019re serving our web app on <strong>localhost:9000<\/strong>. At this point we\u2019d get a same origin policy error. But <a href=\"https:\/\/twitter.com\/jchris\">Chris<\/a> recently added CORS support to Sync Gateway for this purpose. So we don\u2019t have to write one line of server side code :)<\/p>\n\n\n\n<p>CORS allows web apps to access resources on other domains than the origin domain. By enabling CORS on Sync Gateway we\u2019re telling the browser &#8220;Yes, the Sync Gateway domain name is allowed to communicate with this web app&#8221;. Open <strong>sync-gateway-config.json<\/strong> with the extra CORS configuration to enable it on <strong>localhost:9000<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{ \r\n ...\r\n &quot;CORS&quot;: {\r\n   &quot;Origin&quot;: [&quot;https:\/\/localhost:9000&quot;],\r\n   &quot;LoginOrigin&quot;: [&quot;https:\/\/localhost:9000&quot;],\r\n   &quot;Headers&quot;: [&quot;Content-Type&quot;],\r\n   &quot;MaxAge&quot;: 17280000\r\n },\r\n ...\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>Use Sync Gateway 1.1 or later. Start it with the config file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ~\/Downloads\/sync_gateway sync-gateway-config.json\r\n<\/code><\/pre>\n\n\n\n<p>Back in <strong>app.js<\/strong>, update the remoteCouch url accordingly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var SYNC_GATEWAY_URL = &#039;https:\/\/127.0.0.1:4984\/todos\/&#039;;\r\nvar remoteCouch = SYNC_GATEWAY_URL;\r\n<\/code><\/pre>\n\n\n\n<p>Now if we tried to sync the list to Sync Gateway we\u2019d get a 401 Unauthorized error. Let\u2019s fix that by creating a user session with Facebook login.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Authenticating with Sync Gateway<\/h1>\n\n\n\n<p>To authenticate with Sync Gateway we can send a POST request to <strong>\/todos\/_facebook<\/strong> with the access token, if we get back a 200 OK, the browser will set the session cookie returned from Sync Gateway for future push\/pull replications.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function startSyncGatewaySession(accessToken) {\r\n  var request = new XMLHttpRequest();\r\n  request.open(&#039;POST&#039;, SYNC_GATEWAY_URL + &#039;\/_facebook&#039;, true);\r\n  request.setRequestHeader(&#039;Content-Type&#039;, &#039;application\/json&#039;);\r\n  request.onreadystatechange = function() {\r\n    if (request.readyState == 4 &amp;&amp; request.status == 200) {\r\n      console.log(&#039;New SG session, starting sync!&#039;);\r\n      sync();\r\n  };\r\n  request.withCredentials = true;\r\n  request.send(JSON.stringify({&quot;access_token&quot;: accessToken}));\r\n}\r\n<\/code><\/pre>\n\n\n\n<p><strong>Note<\/strong>: It\u2019s important to set <strong>request.withCredentials = true<\/strong> in a CORS request to save the cookie returned from Sync Gateway for future authenticated requests (push\/pull replications).<\/p>\n\n\n\n<p>Call it in <strong>startSessionAndSync<\/strong> passing the <strong>accessToken<\/strong> we got back from Facebook:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function startSessionAndSync(accessToken, userId) {\r\n  migrateGuestToUser(userId);\r\n  startSyncGatewaySession(accessToken);\r\n}\r\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Wrap up<\/h1>\n\n\n\n<p>Now open up your browser, you can test todo items are syncing with another browser window opened or the native apps running TodoLite.<\/p>\n\n\n\n<p>Users can still create tasks without being logged in. But the minute a user logs in, the tasks belong to the user\u2019s list. Providing a guest account feature is one of the many benefits of building for offline-first capabilities.<\/p>\n\n\n\n<p>Notice the <strong>TodoMVC list<\/strong> document is displayed as a task in Chrome. That\u2019s because this example was using the <strong>allDocs<\/strong> query to display tasks.<\/p>\n\n\n\n<p>In the next post, we\u2019ll use Map\/Reduce queries to add the multi-list capability and a profile document as well to share them with other users.<\/p>\n\n\n\n<p>Read more:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sync Gateway CORS configuration:\u00a0\u00a0<a href=\"https:\/\/www.couchbase.com\/developers\/mobile\/#cors-configuration\">https:\/\/www.couchbase.com\/developers\/mobile\/#cors-configuration<\/a><\/li>\n\n\n<li>Enabling cookies in a CORS request: <a href=\"https:\/\/www.html5rocks.com\/en\/tutorials\/cors\/#toc-withcredentials\">https:\/\/www.html5rocks.com\/en\/tutorials\/cors\/#toc-withcredentials<\/a><\/li>\n\n\n<li>Filtered replications with PouchDB: <a href=\"https:\/\/pouchdb.com\/2015\/04\/05\/filtered-replication.html\">https:\/\/pouchdb.com\/2015\/04\/05\/filtered-replication.html<\/a><\/li>\n\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This week, PouchDB v3.4.0\u00a0was released with Couchbase Sync Gateway compatibility. In this post, we\u2019ll take the existing \ufffcTodoMVC example\ufffc and add filtered sync using Facebook authentication. In addition to syncing between Web clients, we\u2019ll change the data model slightly to sync with the existing ToDoLite apps running on iOS\ufffc and \ufffcAndroid: To follow along, you [&hellip;]<\/p>\n","protected":false},"author":51,"featured_media":18,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[9],"tags":[],"ppma_author":[115],"class_list":["post-302","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>First steps with PouchDB &amp; Sync Gateway - The Couchbase Blog<\/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\/pt\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"First steps with PouchDB &amp; Sync Gateway\" \/>\n<meta property=\"og:description\" content=\"This week, PouchDB v3.4.0\u00a0was released with Couchbase Sync Gateway compatibility. In this post, we\u2019ll take the existing \ufffcTodoMVC example\ufffc and add filtered sync using Facebook authentication. In addition to syncing between Web clients, we\u2019ll change the data model slightly to sync with the existing ToDoLite apps running on iOS\ufffc and \ufffcAndroid: To follow along, you [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-12-16T01:03:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"James Nocentini, Technical Writer, Mobile, 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=\"James Nocentini, Technical Writer, Mobile, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\\\/\"},\"author\":{\"name\":\"James Nocentini, Technical Writer, Mobile, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/ec4dfbd349cb4a321fb6a92b71a9a7f6\"},\"headline\":\"First steps with PouchDB &amp; Sync Gateway\",\"datePublished\":\"2015-12-16T01:03:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\\\/\"},\"wordCount\":745,\"commentCount\":9,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Couchbase Mobile\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/\",\"name\":\"First steps with PouchDB &amp; Sync Gateway - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-12-16T01:03:03+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"First steps with PouchDB &amp; 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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/ec4dfbd349cb4a321fb6a92b71a9a7f6\",\"name\":\"James Nocentini, Technical Writer, Mobile, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g09977bdd14473dc23a125f2f74c3e816\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g\",\"caption\":\"James Nocentini, Technical Writer, Mobile, Couchbase\"},\"description\":\"James Nocentini is the Technical Writer in charge of the documentation for Couchbase Mobile. Previously, he worked as a Developer Advocate and before that as a front-end developer for HouseTrip. He also enjoys writing Android tutorials for raywenderlich.com in his spare time.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/james-nocentini\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"First steps with PouchDB &amp; Sync Gateway - The Couchbase Blog","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\/pt\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/","og_locale":"pt_BR","og_type":"article","og_title":"First steps with PouchDB &amp; Sync Gateway","og_description":"This week, PouchDB v3.4.0\u00a0was released with Couchbase Sync Gateway compatibility. In this post, we\u2019ll take the existing \ufffcTodoMVC example\ufffc and add filtered sync using Facebook authentication. In addition to syncing between Web clients, we\u2019ll change the data model slightly to sync with the existing ToDoLite apps running on iOS\ufffc and \ufffcAndroid: To follow along, you [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/","og_site_name":"The Couchbase Blog","article_published_time":"2015-12-16T01:03:03+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"James Nocentini, Technical Writer, Mobile, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"James Nocentini, Technical Writer, Mobile, Couchbase","Est. reading time":"4 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\/"},"author":{"name":"James Nocentini, Technical Writer, Mobile, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ec4dfbd349cb4a321fb6a92b71a9a7f6"},"headline":"First steps with PouchDB &amp; Sync Gateway","datePublished":"2015-12-16T01:03:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\/"},"wordCount":745,"commentCount":9,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","articleSection":["Couchbase Mobile"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb-sync-gateway-todomvc-todolite\/","url":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/","name":"First steps with PouchDB &amp; Sync Gateway - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","datePublished":"2015-12-16T01:03:03+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/first-steps-with-pouchdb--sync-gateway-todomvc-todolite\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"First steps with PouchDB &amp; 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ec4dfbd349cb4a321fb6a92b71a9a7f6","name":"James Nocentini, Technical Writer, Mobile, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g09977bdd14473dc23a125f2f74c3e816","url":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","caption":"James Nocentini, Technical Writer, Mobile, Couchbase"},"description":"James Nocentini is the Technical Writer in charge of the documentation for Couchbase Mobile. Previously, he worked as a Developer Advocate and before that as a front-end developer for HouseTrip. He also enjoys writing Android tutorials for raywenderlich.com in his spare time.","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/james-nocentini\/"}]}},"acf":[],"authors":[{"term_id":115,"user_id":51,"is_guest":0,"slug":"james-nocentini","display_name":"James Nocentini, Technical Writer, Mobile, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/302","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=302"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/302\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/18"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=302"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=302"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=302"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}