|
36 | 36 | import com.google.firebase.storage.StorageTask;
|
37 | 37 | import io.invertase.firebase.app.ReactNativeFirebaseApp;
|
38 | 38 | import io.invertase.firebase.common.SharedUtils;
|
| 39 | +import java.util.HashMap; |
39 | 40 | import java.util.Locale;
|
40 | 41 | import java.util.Map;
|
41 |
| -import java.util.Objects; |
42 | 42 | import javax.annotation.Nullable;
|
43 | 43 |
|
44 | 44 | class ReactNativeFirebaseStorageCommon {
|
@@ -93,15 +93,40 @@ static String getTaskStatus(@Nullable StorageTask<?> task) {
|
93 | 93 | }
|
94 | 94 |
|
95 | 95 | /** Converts a RN ReadableMap into a StorageMetadata instance */
|
96 |
| - static StorageMetadata buildMetadataFromMap(ReadableMap metadataMap, @Nullable Uri file) { |
| 96 | + static StorageMetadata buildMetadataFromMap( |
| 97 | + ReadableMap metadataMap, @Nullable Uri file, @Nullable StorageMetadata existingMetadata) { |
97 | 98 | StorageMetadata.Builder metadataBuilder = new StorageMetadata.Builder();
|
98 | 99 |
|
99 | 100 | if (metadataMap != null) {
|
100 |
| - if (metadataMap.hasKey(KEY_CUSTOM_META)) { |
101 |
| - ReadableMap customerMetaMap = Objects.requireNonNull(metadataMap.getMap(KEY_CUSTOM_META)); |
102 |
| - Map<String, Object> customMeta = customerMetaMap.toHashMap(); |
103 |
| - for (Map.Entry<String, Object> entry : customMeta.entrySet()) { |
| 101 | + if (metadataMap.hasKey(KEY_CUSTOM_META) || (existingMetadata != null)) { |
| 102 | + |
| 103 | + Map<String, Object> customMetadata = new HashMap<>(); |
| 104 | + ReadableMap freshCustomMetadata = metadataMap.getMap(KEY_CUSTOM_META); |
| 105 | + Map<String, Object> existingCustomMetadata = new HashMap<>(); |
| 106 | + |
| 107 | + // Our baseline will be any existing custom metadata if it exists |
| 108 | + if (existingMetadata != null) { |
| 109 | + for (String existingKey : existingMetadata.getCustomMetadataKeys()) { |
| 110 | + customMetadata.put(existingKey, existingMetadata.getCustomMetadata(existingKey)); |
| 111 | + existingCustomMetadata.put( |
| 112 | + existingKey, existingMetadata.getCustomMetadata(existingKey)); |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + // Clobber with any fresh custom metadata if it exists |
| 117 | + if (freshCustomMetadata != null) { |
| 118 | + customMetadata.putAll(freshCustomMetadata.toHashMap()); |
| 119 | + } |
| 120 | + |
| 121 | + for (Map.Entry<String, Object> entry : customMetadata.entrySet()) { |
104 | 122 | metadataBuilder.setCustomMetadata(entry.getKey(), (String) entry.getValue());
|
| 123 | + |
| 124 | + // API contract updates custom metadata as a group but android SDK has key granularity |
| 125 | + // So if freshCustomMetadata exists, for any key that in our merged map but not in |
| 126 | + // freshCustomMetadata, set to null to clear |
| 127 | + if (freshCustomMetadata == null || !freshCustomMetadata.hasKey(entry.getKey())) { |
| 128 | + metadataBuilder.setCustomMetadata(entry.getKey(), null); |
| 129 | + } |
105 | 130 | }
|
106 | 131 | }
|
107 | 132 |
|
@@ -167,29 +192,31 @@ static WritableMap getMetadataAsMap(@Nullable StorageMetadata storageMetadata) {
|
167 | 192 | if (storageMetadata.getCacheControl() != null
|
168 | 193 | && storageMetadata.getCacheControl().length() > 0) {
|
169 | 194 | metadata.putString(KEY_CACHE_CONTROL, storageMetadata.getCacheControl());
|
170 |
| - } else { |
171 |
| - metadata.putNull(KEY_CACHE_CONTROL); |
172 | 195 | }
|
173 | 196 |
|
174 | 197 | if (storageMetadata.getContentLanguage() != null
|
175 | 198 | && storageMetadata.getContentLanguage().length() > 0) {
|
176 | 199 | metadata.putString(KEY_CONTENT_LANG, storageMetadata.getContentLanguage());
|
177 |
| - } else { |
178 |
| - metadata.putNull(KEY_CONTENT_LANG); |
179 | 200 | }
|
180 | 201 |
|
181 |
| - metadata.putString(KEY_CONTENT_DISPOSITION, storageMetadata.getContentDisposition()); |
182 |
| - metadata.putString(KEY_CONTENT_ENCODING, storageMetadata.getContentEncoding()); |
183 |
| - metadata.putString(KEY_CONTENT_TYPE, storageMetadata.getContentType()); |
| 202 | + if (storageMetadata.getContentDisposition() != null |
| 203 | + && storageMetadata.getContentDisposition().length() > 0) { |
| 204 | + metadata.putString(KEY_CONTENT_DISPOSITION, storageMetadata.getContentDisposition()); |
| 205 | + } |
| 206 | + if (storageMetadata.getContentEncoding() != null |
| 207 | + && storageMetadata.getContentEncoding().length() > 0) { |
| 208 | + metadata.putString(KEY_CONTENT_ENCODING, storageMetadata.getContentEncoding()); |
| 209 | + } |
| 210 | + if (storageMetadata.getContentType() != null && storageMetadata.getContentType().length() > 0) { |
| 211 | + metadata.putString(KEY_CONTENT_TYPE, storageMetadata.getContentType()); |
| 212 | + } |
184 | 213 |
|
185 | 214 | if (storageMetadata.getCustomMetadataKeys().size() > 0) {
|
186 | 215 | WritableMap customMetadata = Arguments.createMap();
|
187 | 216 | for (String key : storageMetadata.getCustomMetadataKeys()) {
|
188 | 217 | customMetadata.putString(key, storageMetadata.getCustomMetadata(key));
|
189 | 218 | }
|
190 | 219 | metadata.putMap(KEY_CUSTOM_META, customMetadata);
|
191 |
| - } else { |
192 |
| - metadata.putNull(KEY_CUSTOM_META); |
193 | 220 | }
|
194 | 221 |
|
195 | 222 | return metadata;
|
|
0 commit comments