[expo-asset][Asset.fromURI] Add custom headers option

Please provide the following:

  1. SDK Version:
  2. Platforms(Android/iOS/web/all):
  3. Add the appropriate “Tag” based on what Expo library you have a question on.

I need to add Authorization to the headers when we do Asset.fromURI(uri).downloadAsync(), how do I do that with expo-asset?

It looks like that’s not possible with expo-asset.

You could potentially try patching expo-asset using patch-package. Maybe a patch like this will work. I have not tried it.

diff --git a/node_modules/expo-asset/build/.PlatformUtils.js.swp b/node_modules/expo-asset/build/.PlatformUtils.js.swp
new file mode 100644
index 0000000..64c06f5
Binary files /dev/null and b/node_modules/expo-asset/build/.PlatformUtils.js.swp differ
diff --git a/node_modules/expo-asset/build/Asset.js b/node_modules/expo-asset/build/Asset.js
index 3f6f296..c5f2462 100644
--- a/node_modules/expo-asset/build/Asset.js
+++ b/node_modules/expo-asset/build/Asset.js
@@ -42,7 +42,7 @@ export class Asset {
     }
     static loadAsync(moduleId) {
         const moduleIds = Array.isArray(moduleId) ? moduleId : [moduleId];
-        return Promise.all(moduleIds.map(moduleId => Asset.fromModule(moduleId).downloadAsync()));
+        return Promise.all(moduleIds.map(moduleId => Asset.fromModule(moduleId).downloadAsync(options)));
     }
     static fromModule(virtualAssetModule) {
         if (typeof virtualAssetModule === 'string') {
@@ -118,7 +118,7 @@ export class Asset {
         Asset.byUri[uri] = asset;
         return asset;
     }
-    async downloadAsync() {
+    async downloadAsync(options) {
         if (this.downloaded) {
             return this;
         }
@@ -141,7 +141,7 @@ export class Asset {
                     this.name = AssetUris.getFilename(this.uri);
                 }
             }
-            this.localUri = await downloadAsync(this.uri, this.hash, this.type, this.name);
+            this.localUri = await downloadAsync(this.uri, this.hash, this.type, this.name, options);
             this.downloaded = true;
             this._downloadCallbacks.forEach(({ resolve }) => resolve());
         }
diff --git a/node_modules/expo-asset/build/PlatformUtils.js b/node_modules/expo-asset/build/PlatformUtils.js
index 45493da..4612415 100644
--- a/node_modules/expo-asset/build/PlatformUtils.js
+++ b/node_modules/expo-asset/build/PlatformUtils.js
@@ -29,17 +29,17 @@ export const manifestBaseUrl = Constants.experienceUrl
     ? getManifestBaseUrl(Constants.experienceUrl)
     : null;
 // TODO: how should this behave in bare app with updates? re: hashAssetFiles
-export async function downloadAsync(uri, hash, type, name) {
+export async function downloadAsync(uri, hash, type, name, options) {
     if (IS_MANAGED_ENV) {
-        return _downloadAsyncManagedEnv(uri, hash, type, name);
+        return _downloadAsyncManagedEnv(uri, hash, type, name, options);
     }
-    return _downloadAsyncUnmanagedEnv(uri, hash, type);
+    return _downloadAsyncUnmanagedEnv(uri, hash, type, options);
 }
 /**
  * Check if the file exists on disk already, perform integrity check if so.
  * Otherwise, download it.
  */
-async function _downloadAsyncManagedEnv(uri, hash, type, name) {
+async function _downloadAsyncManagedEnv(uri, hash, type, name, options) {
     const cacheFileId = hash || computeMd5(uri);
     const localUri = `${FileSystem.cacheDirectory}ExponentAsset-${cacheFileId}.${type}`;
     let { exists, md5 } = await FileSystem.getInfoAsync(localUri, {
@@ -47,6 +47,7 @@ async function _downloadAsyncManagedEnv(uri, hash, type, name) {
     });
     if (!exists || (hash !== null && md5 !== hash)) {
         ({ md5 } = await FileSystem.downloadAsync(uri, localUri, {
+            ...options,
             md5: true,
         }));
         if (hash !== null && md5 !== hash) {
@@ -62,7 +63,7 @@ async function _downloadAsyncManagedEnv(uri, hash, type, name) {
  * the hash to compare it with (we don't have hashAssetFiles plugin). Hash is
  * only used for the file name.
  */
-async function _downloadAsyncUnmanagedEnv(uri, hash, type) {
+async function _downloadAsyncUnmanagedEnv(uri, hash, type, options) {
     // TODO: does this make sense to bail out if it's already at a file URL
     // because it's already available locally?
     if (uri.startsWith('file://')) {
@@ -72,7 +73,7 @@ async function _downloadAsyncUnmanagedEnv(uri, hash, type) {
     const localUri = `${FileSystem.cacheDirectory}ExponentAsset-${cacheFileId}.${type}`;
     // We don't check the FileSystem for an existing version of the asset and we
     // also don't perform an integrity check!
-    await FileSystem.downloadAsync(uri, localUri);
+    await FileSystem.downloadAsync(uri, localUri, options);
     return localUri;
 }
 //# sourceMappingURL=PlatformUtils.js.map

If that does work then maybe the Expo team would be willing to accept a similar patch to allow users to specify options when downloading assets.

Thanks @wodin, I simply switched to expo-file-system, it has downloadAsync that accepts headers as options, I can still fetch the assets and cache them.

1 Like