diff --git a/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart b/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart index cf47634c2a95..0b218013ef11 100644 --- a/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart +++ b/packages/cloud_firestore/cloud_firestore/example/integration_test/document_reference_e2e.dart @@ -268,6 +268,16 @@ void runDocumentReferenceTests() { }); group('DocumentReference.get()', () { + test('gets blob data', () async { + final document = await initializeTest('document-get-blob'); + final blob = Blob(Uint8List.fromList([0, 127, 255])); + await document.set({'blob': blob}); + + final snapshot = await document.get(); + + expect(snapshot.get('blob'), blob); + }); + test( 'preserves native error messages when offline', () async { diff --git a/packages/cloud_firestore/cloud_firestore/ios/cloud_firestore/Sources/cloud_firestore/FLTFirebaseFirestoreWriter.m b/packages/cloud_firestore/cloud_firestore/ios/cloud_firestore/Sources/cloud_firestore/FLTFirebaseFirestoreWriter.m index f2656d38dbc9..cdcd84ae3b78 100644 --- a/packages/cloud_firestore/cloud_firestore/ios/cloud_firestore/Sources/cloud_firestore/FLTFirebaseFirestoreWriter.m +++ b/packages/cloud_firestore/cloud_firestore/ios/cloud_firestore/Sources/cloud_firestore/FLTFirebaseFirestoreWriter.m @@ -9,6 +9,9 @@ #import "include/cloud_firestore/Private/FLTFirebaseFirestoreUtils.h" #import "include/cloud_firestore/Public/FLTFirebaseFirestorePlugin.h" +static const UInt8 FLTStandardFieldList = 12; +static const UInt8 FLTStandardFieldMap = 13; + @implementation FLTFirebaseFirestoreWriter : FlutterStandardWriter - (void)writeValue:(id)value { if ([value isKindOfClass:[NSDate class]]) { @@ -51,15 +54,30 @@ - (void)writeValue:(id)value { [self writeValue:extension.databaseURL]; } else if ([value isKindOfClass:[FIRDocumentSnapshot class]]) { - [super writeValue:[self FIRDocumentSnapshot:value]]; + [self writeValue:[self FIRDocumentSnapshot:value]]; } else if ([value isKindOfClass:[FIRLoadBundleTaskProgress class]]) { - [super writeValue:[self FIRLoadBundleTaskProgress:value]]; + [self writeValue:[self FIRLoadBundleTaskProgress:value]]; } else if ([value isKindOfClass:[FIRQuerySnapshot class]]) { - [super writeValue:[self FIRQuerySnapshot:value]]; + [self writeValue:[self FIRQuerySnapshot:value]]; } else if ([value isKindOfClass:[FIRDocumentChange class]]) { - [super writeValue:[self FIRDocumentChange:value]]; + [self writeValue:[self FIRDocumentChange:value]]; } else if ([value isKindOfClass:[FIRSnapshotMetadata class]]) { - [super writeValue:[self FIRSnapshotMetadata:value]]; + [self writeValue:[self FIRSnapshotMetadata:value]]; + } else if ([value isKindOfClass:[NSArray class]]) { + NSArray *list = value; + [self writeByte:FLTStandardFieldList]; + [self writeSize:(UInt32)list.count]; + for (id item in list) { + [self writeValue:item]; + } + } else if ([value isKindOfClass:[NSDictionary class]]) { + NSDictionary *map = value; + [self writeByte:FLTStandardFieldMap]; + [self writeSize:(UInt32)map.count]; + for (id key in map) { + [self writeValue:key]; + [self writeValue:map[key]]; + } } else if ([value isKindOfClass:[NSNumber class]]) { NSNumber *number = (NSNumber *)value; diff --git a/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.cpp b/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.cpp index 46d7f52dd372..fb317c5c1264 100644 --- a/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.cpp +++ b/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "cloud_firestore/plugin_version.h" #include "firebase/app.h" @@ -470,7 +471,8 @@ GetServerTimestampBehaviorFromPigeon( } } -EncodableValue ConvertFieldValueToEncodableValue(const FieldValue& fieldValue) { +EncodableValue CloudFirestorePlugin::ConvertFieldValueToEncodableValue( + const FieldValue& fieldValue) { switch (fieldValue.type()) { case FieldValue::Type::kNull: return EncodableValue(); @@ -492,6 +494,15 @@ EncodableValue ConvertFieldValueToEncodableValue(const FieldValue& fieldValue) { case FieldValue::Type::kString: return EncodableValue(fieldValue.string_value()); + case FieldValue::Type::kBlob: { + std::vector bytes; + if (fieldValue.blob_size() > 0) { + bytes.assign(fieldValue.blob_value(), + fieldValue.blob_value() + fieldValue.blob_size()); + } + return CustomEncodableValue(bytes); + } + case FieldValue::Type::kMap: { EncodableMap encodableMap; for (const auto& [key, val] : fieldValue.map_value()) { @@ -527,8 +538,9 @@ flutter::EncodableMap ConvertToEncodableMap( EncodableMap convertedMap; for (const auto& kv : originalMap) { EncodableValue key = EncodableValue(kv.first); - EncodableValue value = ConvertFieldValueToEncodableValue( - kv.second); // convert FieldValue to EncodableValue + EncodableValue value = + CloudFirestorePlugin::ConvertFieldValueToEncodableValue( + kv.second); // convert FieldValue to EncodableValue convertedMap[key] = value; // insert into the new map } return convertedMap; diff --git a/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.h b/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.h index 84081f5ffd21..e9fea9506f50 100644 --- a/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.h +++ b/packages/cloud_firestore/cloud_firestore/windows/cloud_firestore_plugin.h @@ -27,6 +27,8 @@ class CloudFirestorePlugin : public flutter::Plugin, static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); static firebase::firestore::FieldValue ConvertToFieldValue( const flutter::EncodableValue& variant); + static flutter::EncodableValue ConvertFieldValueToEncodableValue( + const firebase::firestore::FieldValue& fieldValue); CloudFirestorePlugin(); diff --git a/packages/cloud_firestore/cloud_firestore/windows/firestore_codec.cpp b/packages/cloud_firestore/cloud_firestore/windows/firestore_codec.cpp index 238479a4776b..820de87ed734 100644 --- a/packages/cloud_firestore/cloud_firestore/windows/firestore_codec.cpp +++ b/packages/cloud_firestore/cloud_firestore/windows/firestore_codec.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "cloud_firestore_plugin.h" #include "firebase/app.h" @@ -65,6 +66,14 @@ void cloud_firestore_windows::FirestoreCodec::WriteValue( flutter::StandardCodecSerializer::WriteValue(appName, stream); flutter::StandardCodecSerializer::WriteValue(reference.path(), stream); flutter::StandardCodecSerializer::WriteValue(databaseUrl, stream); + } else if (custom_value.type() == typeid(std::vector)) { + const std::vector& bytes = + std::any_cast&>(custom_value); + stream->WriteByte(DATA_TYPE_BLOB); + WriteSize(bytes.size(), stream); + if (!bytes.empty()) { + stream->WriteBytes(bytes.data(), bytes.size()); + } } else if (custom_value.type() == typeid(double)) { // Assuming Double is standard C++ double const double& myDouble = std::any_cast(custom_value);