About 2 years ago, I hacked PouchDB@6 to make it able to run on React Native with attachments support. But the current latest version is 7 now.
Unfortunately, the PouchDB community is not interested in supporting React Native.
So, we have to hack it again for getting v7 to work on RN.
This is the work for building my app called Inkdrop - a cross-platform Markdown note-taking app that uses PouchDB for accomplishing its data sync feature.
React Native has been evolving these 2 years, but FileReader.readAsArrayBuffer is still not implemented.
Creating blobs from ArrayBuffer or ArrayBufferView is not supported as well. I tried to make RN support them by looking into their source code but found that it's hard by design.
So, to deal with attachments in your databases, you have to avoid calling these APIs in PouchDB.
So, you have to hack pouchdb-binary-utils as following. blobOrBufferToBinaryString calls FileReader.readAsArrayBuffer. Call FileReader.readAsDataURL instead:
--- a/packages/node_modules/pouchdb-binary-utils/src/blobOrBufferToBase64-browser.js
+++ b/packages/node_modules/pouchdb-binary-utils/src/blobOrBufferToBase64-browser.js
@@ -1,10 +1,16 @@-import { btoa } from './base64';
-import blobOrBufferToBinaryString from './blobOrBufferToBinaryString';
-
function blobToBase64(blobOrBuffer, callback) {
- blobOrBufferToBinaryString(blobOrBuffer, function (base64) {
- callback(btoa(base64));
- });
+ if (blobOrBuffer.size) {
+ var reader = new FileReader();
+ reader.onloadend = function (e) {
+ const text = e.target.result || '';
+ const base64 = text.split(',')[1];
+ callback(base64);
+ };
+ reader.readAsDataURL(blobOrBuffer);
+ } else {
+ const base64 = blobOrBuffer.toString('base64');
+ setImmediate(() => callback(base64));
+ }
}
In readAsBinaryString, use blobToBase64 instead of readAsArrayBuffer:
--- a/packages/node_modules/pouchdb-binary-utils/src/readAsBinaryString.js
+++ b/packages/node_modules/pouchdb-binary-utils/src/readAsBinaryString.js
@@ -1,32 +1,10 @@-//Can't find original post, but this is close
-//http://stackoverflow.com/questions/6965107/ (continues on next line)
-//converting-between-strings-and-arraybuffers
-function arrayBufferToBinaryString(buffer) {
- var binary = '';
- var bytes = new Uint8Array(buffer);
- var length = bytes.byteLength;
- for (var i = 0; i < length; i++) {
- binary += String.fromCharCode(bytes[i]);
- }
- return binary;
-}
+import blobToBase64 from './blobOrBufferToBase64';
-// shim for browsers that don't support it
function readAsBinaryString(blob, callback) {
- var reader = new FileReader();
- var hasBinaryString = typeof reader.readAsBinaryString === 'function';
- reader.onloadend = function (e) {
- var result = e.target.result || '';
- if (hasBinaryString) {
- return callback(result);
- }
- callback(arrayBufferToBinaryString(result));
- };
- if (hasBinaryString) {
- reader.readAsBinaryString(blob);
- } else {
- reader.readAsArrayBuffer(blob);
- }
+ blobToBase64(blob, (base64) => {
+ const binaryString = atob(base64);
+ callback(binaryString);
+ });
}
export default readAsBinaryString;
PouchDB tries to use Blob but it does not work as expected due to lack of Blob support in RN. So, we have to deal with attachments always in base64: