Created
June 18, 2021 21:42
-
-
Save Abhilash-Chandran/101956c95a5cb391c1d81b004056b06d to your computer and use it in GitHub Desktop.
Firestore document size calculation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "dart:typed_data"; | |
/// An example collection from firestore. | |
/// Covers most datatypes of firestore list in this page. | |
/// https://firebase.google.com/docs/firestore/storage-size#document-size | |
/// Reference field is omitted for now. But shold be easy to implement with the help of cloud_firestore package. | |
final collection = [ | |
{ | |
"name": "John", | |
"lastname": "Doe", | |
"alien": false, | |
"dob": DateTime.now(), | |
"height": 172, | |
"weight": 65.5, | |
"misc": ["area-56", 25, 90.5], | |
"links": {"twitter": "@jd", "google": "[email protected]"}, | |
"avatar": Uint8List.fromList([1,4,6,7,7]) | |
}, | |
{ | |
"name": "John", | |
"lastname": "Doe2", | |
"alien": false, | |
"dob": DateTime.now(), | |
"height": 172, | |
"weight": 65.5, | |
"misc": ["area-56", 25, 90.5], | |
"links": {"twitter": "@jd", "google": "[email protected]"}, | |
"avatar": Uint8List.fromList([1,4,4,5]) | |
} | |
]; | |
/// create an extension on string to return in firestore size | |
extension on String { | |
int fstSize() { | |
return this.length + 1; | |
} | |
} | |
/// extension to create firestore size on num. Covers both int and double | |
extension on num { | |
int fstSize() { | |
return 8; | |
} | |
} | |
/// extension to create firestore size on DateTime | |
extension on DateTime { | |
int fstSize() { | |
return 8; | |
} | |
} | |
/// | |
/// FireStoreSize is aimed at calculating the document size for firestore documents. | |
/// This implementation is based on the reference size from the following page. | |
/// https://firebase.google.com/docs/firestore/storage-size#document-size | |
/// | |
class FireStoreSize { | |
/// Return size in bytes of the provided firestore document [fsDocument]. | |
int getFireStoreDocumentSize(Map<String, dynamic> fsDocument) { | |
int netSizeInBytes = 0; | |
fsDocument.entries.forEach((entry) { | |
// First add the key size to the [netSizeInBytes] | |
netSizeInBytes += entry.key.fstSize(); | |
// assign value to local variable | |
final val = entry.value; | |
// Next depending on the type of the field add the respective size to the [netSizeInBytes] variable. | |
// Recursively call [getFireStoreDocumentSize] method to size of map fields as it represents the firestore map fields. | |
if (val is Map<String, dynamic>) { | |
netSizeInBytes += this.getFireStoreDocumentSize(val); | |
} else if (val is List) { | |
val.forEach((item) { | |
if (item is Map<String, dynamic>) { | |
// For map fields again use a recursive call | |
netSizeInBytes += getFireStoreDocumentSize(item); | |
} else { | |
// For generic fields use the [_fieldSize] method to retrieve field specific size in bytes | |
netSizeInBytes += fieldSize(item); | |
} | |
}); | |
}else{ | |
netSizeInBytes += fieldSize(val); | |
} | |
}); | |
return netSizeInBytes; | |
} | |
/// Returns field type specific size in bytes. | |
/// This method doesnt return reference field sizes as it requires cloud firestore package of dart or flutter to verify the type. | |
/// The [Uint8List] type is used instead of [Blob] from the cloud firetor package for berevity. | |
int fieldSize(dynamic val) { | |
// num,String and DateTime has the respective extension function [fstSize] to return firestoelsere specific sizes. | |
if (val is String) { | |
return val.fstSize(); | |
}else if (val is num) { | |
return val.fstSize(); | |
}else if (val is DateTime) { | |
return val.fstSize(); | |
}else if (val is Uint8List) { | |
// Bytes field should return the size in the bytes. | |
return val.lengthInBytes; | |
} else if (val == null) { | |
// null fields have size of 1 byte by default in firestore. | |
return 1; | |
} | |
return 0; | |
} | |
} | |
void main() { | |
/// Prepare a [FireStoreSize] instance to access the utility functions calculating size of a firestore document. | |
final fss = FireStoreSize(); | |
/// Iterate through the collection of documents are print the size in bytes. | |
/// If the logic is correct it should print | |
collection.asMap().forEach((id, document){ | |
print("Size of document $id is ===> ${fss.getFireStoreDocumentSize(document)}-Bytes"); | |
print("----------------"); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment