{"id":2924,"date":"2017-03-09T03:22:38","date_gmt":"2017-03-09T11:22:38","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2924"},"modified":"2025-06-13T20:09:44","modified_gmt":"2025-06-14T03:09:44","slug":"introduction-offline-data-storage-sync-pouchdb-couchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/introduction-offline-data-storage-sync-pouchdb-couchbase\/","title":{"rendered":"Introducci\u00f3n al almacenamiento y sincronizaci\u00f3n de datos sin conexi\u00f3n con PouchBD y Couchbase"},"content":{"rendered":"<p><a href=\"https:\/\/www.linkedin.com\/in\/pmbanugo\/\"><i><span style=\"font-weight: 400\">Peter Mbanugo<\/span><\/i><\/a><i><span style=\"font-weight: 400\">es un desarrollador de software con experiencia trabajando con Microsoft .NET. Es un apasionado de la creaci\u00f3n de software de calidad, con intereses en torno a las aplicaciones fuera de l\u00ednea y la arquitectura de software.<\/span><\/i><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/es\/offline-first-more-reliable-mobile-apps\/\">Primero fuera de l\u00ednea<\/a> es un enfoque del desarrollo de software distinto del tradicional, en el que la falta de conexi\u00f3n a la red se trata como un error, lo que afecta a la experiencia general del usuario. Con el enfoque \"offline-first\", se empieza con el entorno m\u00e1s restringido y luego se responde a la experiencia de usuario de la aplicaci\u00f3n mejor\u00e1ndola progresivamente a medida que las funcionalidades est\u00e1n disponibles. Para offline-first, se asume que la falta de conexi\u00f3n a la red crea una experiencia de usuario insatisfactoria; por lo tanto, offline-first busca proporcionar la mejor experiencia de usuario posible en todas las condiciones.<\/p>\n<p>El enfoque offline-first viene con algunas preocupaciones tales como, c\u00f3mo almacenar datos o gestionar transacciones cuando se est\u00e1 offline y sincronizarlo con el servidor, c\u00f3mo mantener los datos offline seguros, o c\u00f3mo resolver conflictos de datos si dos usuarios hacen cambios en el mismo registro mientras est\u00e1n offline, etc. Para este post, vamos a ver el almacenamiento de datos sin conexi\u00f3n y la sincronizaci\u00f3n mediante la construcci\u00f3n de una aplicaci\u00f3n web agenda para almacenar los contactos.<\/p>\n<h2>Creaci\u00f3n de la aplicaci\u00f3n de ejemplo<\/h2>\n<p>Nuestra aplicaci\u00f3n de ejemplo ser\u00e1 una aplicaci\u00f3n web que se construir\u00e1 con Bootstrap, jQuery, PouchDB y Couchbase Sync Gateway. Para empezar, vamos a dise\u00f1ar la p\u00e1gina, que incluir\u00e1 un formulario para introducir el nombre del contacto, correo electr\u00f3nico y tel\u00e9fono, y tambi\u00e9n mostrar\u00e1 una lista de contactos guardados.<\/p>\n<h3>Disposici\u00f3n de la p\u00e1gina<\/h3>\n<p>Cree una carpeta para la aplicaci\u00f3n y, a continuaci\u00f3n, descargue <a href=\"https:\/\/getbootstrap.com\/getting-started\/#download\">arranque<\/a> y <a href=\"https:\/\/jquery.com\/download\/\">jQuery<\/a>. Descomprime los archivos y col\u00f3calos en una nueva carpeta llamada <code>activo<\/code>. A\u00f1ade un nuevo archivo llamado <code>index.html<\/code> a su carpeta ra\u00edz y copie el siguiente fragmento en ella.<\/p>\n<pre class=\"lang:xhtml decode:true\">DOCTYPE html\r\n&lt;html lang=&quot;en&quot;&gt;\r\n\r\n&lt;head&gt;\r\n    &lt;meta charset=&quot;utf-8&quot;&gt;\r\n    &lt;title&gt;My Hoodie App&lt;\/title&gt;\r\n    &lt;link rel=&quot;stylesheet&quot; href=&quot;assets\/bootstrap\/bootstrap.min.css&quot;&gt;\r\n&lt;\/head&gt;\r\n\r\n&lt;body&gt;\r\n\r\n    &lt;nav class=&quot;navbar navbar-default&quot;&gt;\r\n        &lt;div class=&quot;container-fluid&quot;&gt;\r\n            &lt;div class=&quot;navbar-header&quot;&gt;\r\n                &lt;a class=&quot;navbar-brand&quot; href=&quot;#&quot;&gt; Agenda&lt;\/a&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/nav&gt;\r\n    &lt;div class=&quot;container&quot;&gt;\r\n\r\n        &lt;div class=&quot;row&quot;&gt;\r\n            &lt;div class=&quot;col-md-10&quot;&gt;\r\n                &lt;h2&gt;A&ntilde;adir nuevo contacto &lt;\/h2&gt;\r\n                &lt;hr \/&gt;\r\n                &lt;form id=&quot;contactForm&quot; class=&quot;form-horizontal&quot; action=&quot;&quot;&gt;\r\n                    &lt;div class=&quot;form-group&quot;&gt;\r\n                        &lt;label for=&quot;name&quot; class=&quot;col-sm-2 control-label&quot;&gt;Nombre&lt;\/label&gt;\r\n                        &lt;div class=&quot;col-sm-10&quot;&gt;\r\n                            &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;name&quot; placeholder=&quot;Nombre&quot;&gt;\r\n                        &lt;\/div&gt;\r\n                    &lt;\/div&gt;\r\n                    &lt;div class=&quot;form-group&quot;&gt;\r\n                        &lt;label for=&quot;mobile&quot; class=&quot;col-sm-2 control-label&quot;&gt;M&oacute;vil&lt;\/label&gt;\r\n                        &lt;div class=&quot;col-sm-10&quot;&gt;\r\n                            &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;mobile&quot; placeholder=&quot;M&oacute;vil&quot;&gt;\r\n                        &lt;\/div&gt;\r\n                    &lt;\/div&gt;\r\n                    &lt;div class=&quot;form-group&quot;&gt;\r\n                        &lt;label for=&quot;email&quot; class=&quot;col-sm-2 control-label&quot;&gt;Correo electr&oacute;nico&lt;\/label&gt;\r\n                        &lt;div class=&quot;col-sm-10&quot;&gt;\r\n                            &lt;input type=&quot;email&quot; class=&quot;form-control&quot; id=&quot;email&quot; placeholder=&quot;Correo electr&oacute;nico&quot;&gt;\r\n                        &lt;\/div&gt;\r\n                    &lt;\/div&gt;\r\n                    &lt;div class=&quot;form-group&quot;&gt;\r\n                        &lt;div class=&quot;col-sm-offset-2 col-sm-10&quot;&gt;\r\n                            &lt;button type=&quot;submit&quot; class=&quot;btn btn-default&quot;&gt;Guardar contacto&lt;\/button&gt;\r\n                        &lt;\/div&gt;\r\n                    &lt;\/div&gt;\r\n                &lt;input type=&quot;hidden&quot; name=&quot;trp-form-language&quot; value=&quot;es&quot;\/&gt;&lt;\/form&gt;\r\n                &lt;hr \/&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n\r\n        &lt;div class=&quot;row&quot;&gt;\r\n            &lt;div class=&quot;col-md-10&quot;&gt;\r\n                &lt;h2&gt;Lista de contactos&lt;\/h2&gt;\r\n                &lt;hr \/&gt;\r\n                &lt;table id=&quot;contactList&quot; class=&quot;table table-bordered&quot;&gt;\r\n                    &lt;thead&gt;\r\n                        &lt;tr&gt;\r\n                            &lt;th&gt;Nombre&lt;\/th&gt;\r\n                            &lt;th&gt;M&oacute;vil&lt;\/th&gt;\r\n                            &lt;th&gt;Correo electr&oacute;nico&lt;\/th&gt;\r\n                            &lt;th&gt;&lt;\/th&gt;\r\n                        &lt;\/tr&gt;\r\n                    &lt;\/thead&gt;\r\n                    &lt;tbody&gt;\r\n\r\n                    &lt;\/tbody&gt;\r\n                &lt;\/table&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n\r\n\r\n        &lt;script src=&quot;assets\/jquery-2.1.0.min.js&quot;&gt;&lt;\/script&gt;\r\n        &lt;script src=&quot;assets\/bootstrap\/bootstrap.min.js&quot;&gt;&lt;\/script&gt;\r\n&lt;\/body&gt;\r\n\r\n&lt;\/html&gt;\r\n<\/pre>\n<p>Lo que tenemos es una p\u00e1gina con un formulario para introducir y guardar contactos, y tambi\u00e9n mostrar la lista de contactos guardados <img decoding=\"async\" src=\"https:\/\/cdn.filestackcontent.com\/hxp63DHySmOWxUCT7aIw\" alt=\"page layout\" \/><\/p>\n<h3>Acceso\/almacenamiento de datos sin conexi\u00f3n<\/h3>\n<p>Los datos se convierten en una de las principales preocupaciones de una aplicaci\u00f3n Offline-First. Cualquier aplicaci\u00f3n que funcione offline tiene que lidiar con el acceso y almacenamiento de datos offline, que se gestionar\u00e1 almacenando los datos en el cliente, y lidiando con el problema de sincronizar los datos de forma fiable. Existen varias bases de datos del lado del cliente para aplicaciones m\u00f3viles y web, incluyendo Couchbase Lite y Cloudant Sync para clientes m\u00f3viles y de escritorio, e IndexedDB y Web SQL para navegadores. Para nuestro ejemplo utilizaremos PouchDB, una API de base de datos del lado del cliente en JavaScript que sigue el modelo de la API de CouchDB. PouchDB abstrae las diferentes bases de datos soportadas por los navegadores y sus diferentes interfaces de programaci\u00f3n. Fue creada para ayudar a construir aplicaciones que funcionen tan bien offline como online, almacenando los datos localmente mientras se est\u00e1 offline y sincroniz\u00e1ndolos con el servidor y otros clientes conectados cuando se est\u00e1 online.<\/p>\n<p>Tambi\u00e9n utilizar\u00e9 <a href=\"https:\/\/www.npmjs.com\/package\/@hoodie\/store-client\">tienda-cliente de sudaderas<\/a>, un plugin de PouchDB para la persistencia de datos y la sincronizaci\u00f3n offline. Prefiero trabajar con esta librer\u00eda por la API disponible para trabajar con datos y sincronizaci\u00f3n. A\u00f1ade autom\u00e1ticamente timestamps cuando a\u00f1ado nuevos datos. A\u00f1adir\u00e9 este plugin as\u00ed como PouchDB usando el npm con el siguiente comando o descarg\u00e1ndolo desde aqu\u00ed <a href=\"https:\/\/unpkg.com\/@hoodie\/store-client@7.0.1\/dist\/hoodie-store-client.js\">tienda-cliente<\/a> &amp; <a href=\"https:\/\/github.com\/pouchdb\/pouchdb\/releases\/download\/6.1.2\/pouchdb-6.1.2.min.js\">BolsaBD<\/a>. Tenga en cuenta que estoy usando PouchDB 6.1.2 y hoodie-store-client 7.0.1.<\/p>\n<pre><code>npm install --save pouchdb\r\n\r\nnpm install --save @hoodie\/store-client<\/code><\/pre>\n<p>Ahora incluye estos archivos en la p\u00e1gina.<\/p>\n<pre><code class=\"language-html\">\r\n<\/code><\/pre>\n<p>Una vez hecho esto, a\u00f1adimos un nuevo archivo llamado <code>index.js<\/code> en el <code>activo<\/code> y a\u00f1adimos un enlace a este archivo en la p\u00e1gina. Dentro de este archivo, lo primero que hacemos es inicializar un objeto Store con el nombre de la base de datos y la URL al servidor para la sincronizaci\u00f3n.<\/p>\n<pre><code class=\"language-javascript\">$(function(){\r\n    var store = new Store('ejemplo', { remoto: 'https:\/\/localhost:4984\/example', PouchDB: PouchDB });\r\n});<\/code><\/pre>\n<p>A\u00f1ade el siguiente c\u00f3digo para guardar el valor introducido en el formulario y a\u00f1adirlo tambi\u00e9n a la lista de contactos de la p\u00e1gina.<\/p>\n<pre><code class=\"language-javascript\">$('#contactForm').submit(function(event) {\r\n    event.preventDefault();\r\n\r\n    var name = $('#name').val();\r\n    var email = $('#email').val();\r\n    var mobile = $('#mobile').val();\r\n\r\n    \/\/ Guarda el contacto en la base de datos\r\n    store.add({\r\n        nombre: nombre,\r\n        m\u00f3vil: m\u00f3vil,\r\n        email: email\r\n    });\r\n\r\n    $('#contactForm')[0].reset();\r\n    });\r\n\r\n    \/\/a\u00f1ade un nuevo contacto a la p\u00e1gina\r\n    function addNewContactToList(contacto) {\r\n    var newContact = '' + contact.name + '' + contact.mobile + '' + contact.email + '\r\n<\/code><\/pre>\n<p>' $(\"#contactList tbody\").append(newContact); } \/\/cuando se a\u00f1ade una nueva entrada a la base de datos, ejecuta la funci\u00f3n correspondiente store.on('add', addNewContactToList); function loadContacts() { store.findAll().then(function(contacts) { var tbody = \"; $.each(contacts, function (i, contact) { var row = '<\/p>\n<pre><code class=\"language-javascript\">' + contact.name + '' + contact.mobile + '' + contact.email + '\r\n<\/code><\/pre>\n<p>'; tbody += row; }); $(\"#contactList tbody\").html(\").html(tbody); }); } \/\/ cuando el sitio se carga en el navegador, \/\/ cargamos todos los contactos guardados previamente desde hoodie loadContacts();<\/p>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<p>Utilic\u00e9 <code>almacenar.a\u00f1adir<\/code> para insertar en la base de datos local, y luego escuchar los eventos utilizando <code>store.on<\/code>en particular el <code>a\u00f1ada<\/code> y esto ser\u00e1 \u00fatil cuando empecemos a sincronizar datos y mostrar\u00e1 nuevos datos despu\u00e9s de una sincronizaci\u00f3n completa con bases de datos remotas. Tambi\u00e9n he a\u00f1adido una funci\u00f3n para mostrar los datos locales cuando la p\u00e1gina se carga o se actualiza. Podemos comprobar que podemos guardar los datos localmente.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cdn.filestackcontent.com\/bCOkY59qR0KfPA3YurQY\" alt=\"local data\" \/><\/p>\n<p>Ahora tenemos acceso\/almacenamiento de datos offline funcionando. Con lo que hemos hecho hasta ahora, deber\u00edas empezar a ver el cambio de mentalidad o proceso de pensamiento. Esto es almacenar los datos localmente primero, y despu\u00e9s empujar los cambios al servidor cuando est\u00e9 online. Nuestro siguiente paso es sincronizar estos datos con un servidor Couchbase. Para que esto funcione, necesitamos Couchbase Sync Gateway.<\/p>\n<h3>Pasarela de sincronizaci\u00f3n<\/h3>\n<p>Sync Gateway es una aplicaci\u00f3n web segura con APIs de sincronizaci\u00f3n, REST, stream, batch y eventos para acceder y sincronizar datos a trav\u00e9s de la web. Sync Gateway permite, entre otras cosas, la replicaci\u00f3n segura de datos entre Couchbase Server y<br \/>\nCouchbase Lite y\/o PouchDB. Para una gu\u00eda r\u00e1pida sobre c\u00f3mo instalarlo, consulta esto <a href=\"https:\/\/www.couchbase.com\/blog\/es\/getting-comfortable-couchbase-mobile-installing-sync-gateway\/\">gu\u00eda<\/a>. Si Sync Gateway est\u00e1 instalado, ser\u00e1 accesible desde el <code>https:\/\/localhost:4984<\/code> cuando se inicia. Si recuerdas, ten\u00edamos una url similar al inicializar el <code>Tienda<\/code> para utilizar PouchDB pero con un objeto adicional <code>\/ejemplo<\/code> como ap\u00e9ndice. El ap\u00e9ndice extra especifica el nombre de la base de datos con la que sincronizamos. Para que nuestra aplicaci\u00f3n utilice el almacenamiento y la sincronizaci\u00f3n de datos sin conexi\u00f3n, iniciemos el servicio Sync Gateway y actualicemos el JavaScript de la p\u00e1gina para la sincronizaci\u00f3n autom\u00e1tica. Utilizar\u00e9 la configuraci\u00f3n de Sync Gateway.<\/p>\n<pre><code class=\"language-json\">{\r\n    \"log\":[\"*\"],\r\n    \"databases\": {\r\n        \"example\": {\r\n            \"server\":\"walrus:\",\r\n            \"users\": {\r\n                \"GUEST\": {\r\n                    \"disabled\": false,\r\n                    \"admin_channels\": [\"*\"]\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \"CORS\": {\r\n        \"Origin\": [\"https:\/\/127.0.0.1:8801\"],\r\n        \"LoginOrigin\": [\"https:\/\/127.0.0.1:8801\"],\r\n        \"Headers\": [\"Content-Type\"],\r\n        \"MaxAge\": 17280000\r\n    }\r\n}<\/code><\/pre>\n<p>Tenemos una configuraci\u00f3n b\u00e1sica que establecer\u00e1 una conexi\u00f3n con la base de datos de ejemplo y utilizar\u00e1 la opci\u00f3n de almacenamiento en memoria (walrus), que en producci\u00f3n deber\u00edamos cambiar para que apunte a un servidor Couchbase. Tambi\u00e9n hemos a\u00f1adido la configuraci\u00f3n para permitir compartir recursos entre or\u00edgenes para nuestra aplicaci\u00f3n que est\u00e1 en un puerto diferente. Ahora tenemos que iniciar el servicio Sync Gateway ejecutando el siguiente comando en el terminal<\/p>\n<p><code>$ .\/bin\/sync_gateway my-config\/phonebook-config.json<\/code><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cdn.filestackcontent.com\/zVqxU5R7QUOodulPXhxr\" alt=\"start sync gateway\" \/><\/p>\n<p>Con Sync Gateway iniciado tenemos que actualizar el c\u00f3digo para la sincronizaci\u00f3n continua. A\u00f1ada el siguiente c\u00f3digo a <code>index.js<\/code><\/p>\n<pre><code class=\"language-javascript\">store.connect();<\/code><\/pre>\n<p>El c\u00f3digo anterior utiliza la tienda de sudaderas <code>conecte<\/code> para decirle a PouchDB que inicie una replicaci\u00f3n continua con la base de datos remota. Una vez que recargamos nuestra base de datos, los datos que agregamos en el paso anterior se sincronizar\u00e1n autom\u00e1ticamente con el servidor. Puedes ver esto usando la URL de administraci\u00f3n de Sync Gateway <a href=\"https:\/\/localhost:4985\/_admin\/db\/example\">https:\/\/localhost:4985\/_admin\/db\/example<\/a>.<\/p>\n<h2>Resumen<\/h2>\n<p>Con todo lo que tenemos ahora, la aplicaci\u00f3n funciona bien con el almacenamiento de datos sin conexi\u00f3n y la sincronizaci\u00f3n entre dispositivos en tiempo real. Dado que tenemos una aplicaci\u00f3n web y los usuarios probablemente abrir\u00e1n la p\u00e1gina cuando est\u00e9n desconectados o con una conexi\u00f3n inestable, podemos hacer que la p\u00e1gina se cargue durante estas situaciones e incluso que se cargue r\u00e1pidamente utilizando Service Worker, Cache API y Fetch API almacenando en cach\u00e9 el activo de la aplicaci\u00f3n e interceptando las solicitudes a estos y devolviendo las respuestas almacenadas en cach\u00e9. Esto va m\u00e1s all\u00e1 del alcance de esta entrada del blog, pero creo que he mostrado lo f\u00e1cil que es hacer que los datos est\u00e9n disponibles cuando no se est\u00e1 conectado y mantener todos los clientes del navegador conectados en sincron\u00eda, mientras que la aplicaci\u00f3n carga los datos r\u00e1pidamente, y tambi\u00e9n el cambio de mentalidad de desarrollar Offline-First.<\/p>\n<p>A continuaci\u00f3n encontrar\u00e1 GIFs para ver c\u00f3mo funciona<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cdn.filestackcontent.com\/yzpggAfQj2Wa44MPfym9\" alt=\"gif-1.gif\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cdn.filestackcontent.com\/4B884JsyS4aNs2V3wNKv\" alt=\"gif-2.gif\" \/><\/p>\n<p>Puede obtener el c\u00f3digo fuente <a href=\"https:\/\/github.com\/pmbanugo\/couchbase-phonebook\">aqu\u00ed<\/a> \u00a1y dale una vuelta!<\/p>","protected":false},"excerpt":{"rendered":"<p>Offline-first es un enfoque del desarrollo de software distinto del tradicional, en el que la falta de conexi\u00f3n a la red se trata como un error, lo que afecta a la experiencia general del usuario. Con el enfoque tradicional, se empieza con el entorno m\u00e1s restringido y despu\u00e9s se responde a la experiencia de usuario de la aplicaci\u00f3n mejor\u00e1ndola progresivamente a medida que las funcionalidades est\u00e1n disponibles. Para offline-first, se asume que la falta de conexi\u00f3n a la red crea una experiencia de usuario insatisfactoria; por tanto, offline-first trata de ofrecer la mejor experiencia de usuario posible en todas las condiciones.<\/p>","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":[7667,1810,2366],"tags":[1541],"ppma_author":[9026],"class_list":["post-2924","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-lite","category-couchbase-mobile","category-sync-gateway","tag-pouchdb"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Offline Data Storage + Sync with PouchBD and Couchbase<\/title>\n<meta name=\"description\" content=\"This Couchbase post takes a look at offline data storage and synchronization by building a web phonebook app to store contacts with PouchBD and Couchbase.\" \/>\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\/es\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introduction to offline data storage and sync with PouchBD and Couchbase\" \/>\n<meta property=\"og:description\" content=\"This Couchbase post takes a look at offline data storage and synchronization by building a web phonebook app to store contacts with PouchBD and Couchbase.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-09T11:22:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:09:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.filestackcontent.com\/hxp63DHySmOWxUCT7aIw\" \/>\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=\"7 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"Introduction to offline data storage and sync with PouchBD and Couchbase\",\"datePublished\":\"2017-03-09T11:22:38+00:00\",\"dateModified\":\"2025-06-14T03:09:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\"},\"wordCount\":1212,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"pouchdb\"],\"articleSection\":[\"Couchbase Lite\",\"Couchbase Mobile\",\"Sync Gateway\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\",\"name\":\"Offline Data Storage + Sync with PouchBD and Couchbase\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-03-09T11:22:38+00:00\",\"dateModified\":\"2025-06-14T03:09:44+00:00\",\"description\":\"This Couchbase post takes a look at offline data storage and synchronization by building a web phonebook app to store contacts with PouchBD and Couchbase.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#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\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introduction to offline data storage and sync with PouchBD and Couchbase\"}]},{\"@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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\",\"@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\/es\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Offline Data Storage + Sync with PouchBD and Couchbase","description":"Este post de Couchbase echa un vistazo al almacenamiento y sincronizaci\u00f3n de datos offline construyendo una aplicaci\u00f3n web de agenda para almacenar contactos con PouchBD y Couchbase.","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\/es\/introduction-offline-data-storage-sync-pouchdb-couchbase\/","og_locale":"es_MX","og_type":"article","og_title":"Introduction to offline data storage and sync with PouchBD and Couchbase","og_description":"This Couchbase post takes a look at offline data storage and synchronization by building a web phonebook app to store contacts with PouchBD and Couchbase.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/introduction-offline-data-storage-sync-pouchdb-couchbase\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-03-09T11:22:38+00:00","article_modified_time":"2025-06-14T03:09:44+00:00","og_image":[{"url":"https:\/\/cdn.filestackcontent.com\/hxp63DHySmOWxUCT7aIw","type":"","width":"","height":""}],"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":"7 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"Introduction to offline data storage and sync with PouchBD and Couchbase","datePublished":"2017-03-09T11:22:38+00:00","dateModified":"2025-06-14T03:09:44+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/"},"wordCount":1212,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["pouchdb"],"articleSection":["Couchbase Lite","Couchbase Mobile","Sync Gateway"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/","url":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/","name":"Offline Data Storage + Sync with PouchBD and Couchbase","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-03-09T11:22:38+00:00","dateModified":"2025-06-14T03:09:44+00:00","description":"Este post de Couchbase echa un vistazo al almacenamiento y sincronizaci\u00f3n de datos offline construyendo una aplicaci\u00f3n web de agenda para almacenar contactos con PouchBD y Couchbase.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#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\/introduction-offline-data-storage-sync-pouchdb-couchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Introduction to offline data storage and sync with PouchBD and Couchbase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@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, Directora de la Comunidad de Desarrolladores, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@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 es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro bolet\u00edn mensual para desarrolladores.","url":"https:\/\/www.couchbase.com\/blog\/es\/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 es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro bolet\u00edn mensual para desarrolladores."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2924","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2924"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2924\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2924"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2924"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2924"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2924"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}