pouchdb-react-native: Storing an attachment fails

Hi, I tried to store an attachment as an inline attachment and also tried the db.putAttachment method. But I did not get it working. Also checked your example implementation.

I tried

var attachment = "TGVnZW5kYXJ5IGhlYXJ0cywgdGVhciB1cyBhbGwgYXBhcnQKTWFrZS" +
              "BvdXIgZW1vdGlvbnMgYmxlZWQsIGNyeWluZyBvdXQgaW4gbmVlZA==";
db.putAttachment(doc._id, 'att.txt', doc.rev, attachment, 'text/plain');

But it fails with a strange message (Xcode console)

[tid:com.facebook.react.JavaScript] { [ReferenceError: Can't find variable: FileReaderSync]
  line: 133952,
  column: 35,
  sourceURL: 'http://192.168.0.62.xip.io:8081/index.ios.bundle?platform=ios&dev=true&minify=false' }

It is the same with inline attachments. Storing documents without attachments works fine.

Tested with ios: 9.3 (ipad device and iphone 6 simulator). Did you get storing Attachments working?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 18

Commits related to this issue

Most upvoted comments

Just for info: Others might ran in the storage limitation of Android. On Android asyncstorage has a limitation of 6 MB per default. I am also temporarily storing images for synchronization in PouchDB so this limit is reached very quickly. I overcome this by setting the maximum size when starting the app in MainApplication.getPackages() using

long size = 50L * 1024L * 1024L; // 50 MB com.facebook.react.modules.storage.ReactDatabaseSupplier.getInstance(getApplicationContext()).setMaximumSize(size);

Hi, got it working (workaround) for Base64 strings but not for Blobs yet.

The problem is in pouchdb-adapter-asyncstorage/bulk_docs.js using wrong data types.

  1. It calls the function readAsArrayBuffer() in pouchdb-binary-utils/lib/index.js with Uint8Array and not using a Blob as expected (called from binaryMd5())
  2. global.btoa(binData) throws an error if the base64 contains non latin1 characters

I added a check for Blob in pouchdb-binary-utils/lib/index.js in the function readAsArrayBuffer(), line 61 ff. since a Uint8Array is used and not a Blob

function readAsArrayBuffer(blob, callback) {
  if (typeof FileReader === 'undefined') {
    // fix for Firefox in a web worker:
    // https://bugzilla.mozilla.org/show_bug.cgi?id=901097
    return callback(new FileReaderSync().readAsArrayBuffer(blob));
  }

  if (blob instanceof Blob) {
    var reader = new FileReader();
    reader.onloadend = function (e) {
      var result = e.target.result || new ArrayBuffer(0);
      callback(result);
    };
    reader.readAsArrayBuffer(blob);
  }
  else {
    callback(blob.buffer);
  }
}

I also did a change in pouchdb-adapter-asyncstorage/bulk_docs.js since the method global.btoa(binData) throws an error if special characters are within the base64 or reading handling image data. Error message with global.btoa(binData): DOMException: Failed to execute btoa on WorkerGlobalScope: The string to be encoded contains characters outside of the Latin1 range.

I just use the already available base64 string.

Change in bulk_docs.js:

...
              const dbAttachment = [
                forAttachment(meta.digest), {
                  digest: meta.digest,
                  content_type: meta.content_type,
                  data: (typeof attachment.data === 'string') ?  attachment.data : global.btoa(binData) //global.btoa(binData)
                }]
              resolve({attachment: meta, dbAttachment})
...

I think this type checks and conversion have to be done properly in bulk_docs.js that there are no changes necessary in pouchdb-binary-utils.

Hope this helps a bit for further investigation.