如何使用 PouchDB (leveldb) 与 Cloudant 或任何其他支持 couchDB 和同步的数据库连接我的电子应用程序

问题描述

我正在使用 pouchDB 创建一个电子应用程序,我希望该应用程序能够处理不同的客户并在他们之间同步数据。例如,我正在制作教程:https://github.com/nolanlawson/pouchdb-getting-started-todo,我将代码改编为电子,并在 cloudant 创建了一个 nosql 数据库

目前我可以保存数据,但无法与位于 cloudant 中的远程数据库同步。这是我用来在两个数据库之间同步数据的端点。

enter image description here

这是我得到的错误

enter image description here

这是我的 script.js 的代码

(function() {

  'use strict';

  var $ = document.querySelector.bind(document);

  var ENTER_KEY = 13;
  var newTodoDom = document.getElementById('new_todo');
  var syncDom = document.getElementById('sync-wrapper');
 

  // EDITING STARTS HERE (you dont need to edit anything above this line)
  var NodePouchDB = require('pouchdb');
  var db = new NodePouchDB('todos');

  var couchdb = require('Felix-couchdb')
  var remoteCouch = couchdb.createClient(5984,'https://ac725f4e-29ec-4614-8e96-02ebc74a529b-bluemix.cloudant.com/')


  db.info(function(err,info) {
    console.log("is working",info)
    db.changes({
      since: info.update_seq,live: true
    }).on('change',showTodos);
  });

  // We have to create a new todo document and enter it in the database
  function addTodo(text) {
    var todo = {
      _id: new Date().toISOString(),title: text,completed: false
    };
    db.put(todo).then(function (result) {
      console.log("everything is A-OK");
      console.log(result);
    }).catch(function (err) {
      console.log('everything is terrible');
      console.log(err);
    });
  }

  // Show the current list of todos by reading them from the database
  function showTodos() {
    db.allDocs({include_docs: true,descending: true}).then(function(doc) {
      redrawTodosUI(doc.rows);
    }).catch(function (err) {
      console.log(err);
    });
  }

  function checkBoxChanged(todo,event) {
    todo.completed = event.target.checked;
    console.log(todo);
    db.put(todo);
  }

  // User pressed the delete button for a todo,delete it
  function deleteButtonpressed(todo) {
    db.remove(todo);
  }

  // The input Box when editing a todo has blurred,we should save
  // the new title or delete the todo if the title is empty
  function todoblurred(todo,event) {
    var trimmedText = event.target.value.trim();
    if (!trimmedText) {
      db.remove(todo);
    } else {
      todo.title = trimmedText;
      db.put(todo);
    }
  }

  // Initialise a sync with the Remote Server
  function sync() {
    syncDom.setAttribute('data-sync-state','syncing');
    
    var opts = {live: true};
    db.sync(remoteCouch,opts,syncError);
  }

  // EDITING STARTS HERE (you dont need to edit anything below this line)

  // There was some form or error syncing
  function syncError() {
    syncDom.setAttribute('data-sync-state','error');
  }

  // User has double clicked a todo,display an input so they can edit the title
  function todoDblClicked(todo) {
    var div = document.getElementById('li_' + todo._id);
    var inputEditTodo = document.getElementById('input_' + todo._id);
    div.className = 'editing';
    inputEditTodo.focus();
  }

  // If they press enter while editing an entry,blur it to trigger save
  // (or delete)
  function todoKeypressed(todo,event) {
    if (event.keyCode === ENTER_KEY) {
      var inputEditTodo = document.getElementById('input_' + todo._id);
      inputEditTodo.blur();
    }
  }

  // Given an object representing a todo,this will create a list item
  // to display it.
  function createtodoListItem(todo) {
    var checkBox = document.createElement('input');
    checkBox.className = 'toggle';
    checkBox.type = 'checkBox';
    checkBox.addEventListener('change',checkBoxChanged.bind(this,todo));

    var label = document.createElement('label');
    label.appendChild( document.createTextNode(todo.title));
    label.addEventListener('dblclick',todoDblClicked.bind(this,todo));

    var deleteLink = document.createElement('button');
    deleteLink.className = 'destroy';
    deleteLink.addEventListener( 'click',deleteButtonpressed.bind(this,todo));

    var divdisplay = document.createElement('div');
    divdisplay.className = 'view';
    divdisplay.appendChild(checkBox);
    divdisplay.appendChild(label);
    divdisplay.appendChild(deleteLink);

    var inputEditTodo = document.createElement('input');
    inputEditTodo.id = 'input_' + todo._id;
    inputEditTodo.className = 'edit';
    inputEditTodo.value = todo.title;
    inputEditTodo.addEventListener('keypress',todoKeypressed.bind(this,todo));
    inputEditTodo.addEventListener('blur',todoblurred.bind(this,todo));

    var li = document.createElement('li');
    li.id = 'li_' + todo._id;
    li.appendChild(divdisplay);
    li.appendChild(inputEditTodo);

    if (todo.completed) {
      li.className += 'complete';
      checkBox.checked = true;
    }

    return li;
  }

  function redrawTodosUI(todos) {
    var ul = document.getElementById('todo-list');
    ul.innerHTML = '';
    todos.forEach(function(todo) {
      ul.appendChild(createtodoListItem(todo.doc));
    });
  }

  function newTodoKeyPressHandler( event ) {
    if (event.keyCode === ENTER_KEY) {
      addTodo(newTodoDom.value);
      newTodoDom.value = '';
    }
  }

  function addEventListeners() {
    newTodoDom.addEventListener('keypress',newTodoKeyPressHandler,false);
  }

  addEventListeners();
  showTodos();

  if (remoteCouch) {
    sync();
  }

})();

解决方法

要找出问题所在,您能否验证您是否可以正常与 Cloudant 数据库对话,即在命令行中使用 curl?使用 curl,通过文档的 _id 获取文档,可能是您使用 Cloudant 仪表板手动创建的文档。这应该可以解决身份验证的任何问题:我注意到您使用的是 IAM,这并不总是直接的——据我所知,PouchDB 不支持(或者不支持,我上次看)。>

如果这是问题所在,请使用 IAM+Legacy 凭证创建一个新的 Cloudant 实例。