13

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.

Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?

Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size

function calcFirestoreDocSize(collectionName, docId, docObject) {
    let docNameSize = encodedLength(collectionName) + 1 + 16
    let docIdType = typeof(docId)
    if(docIdType === 'string') {
        docNameSize += encodedLength(docId) + 1
    } else {
        docNameSize += 8
    }  
    let docSize = docNameSize + calcObjSize(docObject)

    return  docSize
}
function encodedLength(str) {
    var len = str.length;
    for (let i = str.length - 1; i >= 0; i--) {
        var code = str.charCodeAt(i);
        if (code > 0x7f && code <= 0x7ff) {
            len++;
        } else if (code > 0x7ff && code <= 0xffff) {
            len += 2;
        } if (code >= 0xDC00 && code <= 0xDFFF) {
            i--;
        }
    }
    return len;
}

function calcObjSize(obj) {
    let key;
    let size = 0;
    let type = typeof obj;

    if(!obj) {
        return 1
    } else if(type === 'number') {
        return 8
    } else if(type === 'string') {
        return encodedLength(obj) + 1
    } else if(type === 'boolean') {
        return 1
    } else if (obj instanceof Date) {
        return 8
    } else if(obj instanceof Array) {
        for(let i = 0; i < obj.length; i++) {
            size += calcObjSize(obj[i])
        }
        return size
    } else if(type === 'object') {

        for(key of Object.keys(obj)) {
            size += encodedLength(key) + 1 
            size += calcObjSize(obj[key])
        }
        return size += 32
    }
}
pwray
  • 1,075
  • 1
  • 10
  • 19
  • Did you ever find a solution to this, or test your own implementation? – emulcahy Jun 05 '18 at 23:00
  • I tried out your implementation with Google's sample data (Task id:5730082031140864) from the docs you linked. Expected size is 131 bytes, your implementation gave 230 bytes. This is actually close enough for my purposes, I just wanted to make sure I wasn't approaching the limit. So thank you! – emulcahy Jun 05 '18 at 23:13
  • I just checked this against the current examples and it's almost perfect. It's only off because you don't need the +1 in the first line (document names only need the extra +16 unlike strings)... thanks!! – Philberg Apr 20 '19 at 05:16

1 Answers1

2

In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:

In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • This is awesome. Would be nice to have it directly in the FB SDK. I am trying to get grasp of how big my documents are (lot of nested data) so it's pretty hard to calculate manually. – pagep Mar 01 '21 at 23:00
  • 1
    @pagep Till they add that as a part of the SDK, this library does the trick. – Alex Mamo Mar 02 '21 at 06:37
  • 1
    Yep, but I have web only app. I might try to port the lib into JS - hopefully if I find a time. Chers – pagep Mar 02 '21 at 09:32
  • @pagep Hehe sounds good. Good luck with that ;) – Alex Mamo Mar 02 '21 at 11:27