I’m using Firebase to load addressable assets remotely, and that loading is working with no issues - however, I seem to be unable to get the device to cache the assets - it doesn’t seem to save anything to local storage, and every time I restart the app, it re-downloads the files. This is without updating or rebuilding the addressables in any way.
Everything I’ve read suggests that caching should happen automatically, but that’s not been the case for me with Android or StandaloneWindows64 builds.
Attached are pictures of my addressable group settings, AddressableAssetsSettings, and the CacheInitializationSettings I’ve added (have attempted this with and without the CacheInitializationSettings).
Any ideas would be much appreciated. Thanks in advance!
Thanks for the reply! It does append a couple of query params, but as far as I can tell the values of those params remain constant per file - though it’s a promising lead.
Having investigated that code myself, it looked like the decision for whether or not something should be cached happens before it reaches Firebase code, but I could be wrong there.
Ran some tests on this, it appears as long as the last segment of the url contains the last segment of assetbundle url that was passed in the previous time it should find it in cache. I can append and prepend bogus parameters to the last segment and it’ll still successfully find the bundle in cache. ’
So I think we can rule out the parameter part, if you’re sure the name of the last segment doesn’t change the next suspect would be that hash that’s passed in. I haven’t looked at the firebase implementation but I assume it just uses UnityWebrequest.GetAssetbundle after resolving the right url, which takes a hash and crc as parameters.
The way it’s implemented, once it knows the HTTPS download URL it creates a new ResourceLocationBase with that resolved URL, specifying AssetBundleProvider as the provider type - see line 42 here:
so in theory, the hash is calculated the same way as it usually is by “normal” remote asset bundles.
Can you verify loading assetbundles to cache outside of the addressables environment works as expected?
Just attach below script, this works on my end:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class AssetBundleDownloader : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Caching.ClearCache();
StartCoroutine(DownloadBundle("https://s3-eu-west-1.amazonaws.com/nils.mysmilez.nl/Android/packedassets_assets_assets/vrworlds/loft/loftvr.prefab_2cf8877c87095e8687e16fe0d13d105f.bundle"));
}
// Update is called once per frame
void Update()
{
}
IEnumerator DownloadBundle(string link)
{
UnityWebRequest download = UnityWebRequestAssetBundle.GetAssetBundle(link + "?statictoken=123", Hash128.Parse("123456789"));
download.SendWebRequest();
while(!download.isDone)
{
Debug.Log(download.downloadProgress);
yield return null;
}
if(!(download.isNetworkError || download.isHttpError))
{
Debug.Log("First download is done, this one should have taken quite a long time");
//bundle should now be cached
if(Caching.IsVersionCached(link + "?statictoken=456&extraparam=hello", Hash128.Parse("123456789")))
{
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle("https://s3-eu-west-1.amazonaws.com/beng.mysmilez.nl/content/loftvr.prefab_2cf8877c87095e8687e16fe0d13d105f.bundle" + "?statictoken=456", Hash128.Parse("123456789"));
request.SendWebRequest();
while(!request.isDone)
{
Debug.Log(request.downloadProgress);
yield return null;
}
if(!(request.isNetworkError || request.isHttpError))
{
Debug.Log("Second download is done, this one should have finished immediately");
}
}
else
Debug.LogError("bundle is not cached");
}
}
}
If I run it a second time, the cache seems to persist.
Trying the https:// full URL, the gs:// URL, the name of the bundle with .bundle at the end and without, I wasn’t able to see any cached versions for any of those keys.
Additionally, I put breakpoints on all calls to Caching.* within the Addressables and Firebase Addressables packages, and none got any hits at all.
EDIT: I now see that AssetBundleProvider calls UnityWebRequestAssetBundle.GetAssetBundle, which eventually gets down to an extern DownloadHandlerAssetBundle.CreateCached_Injected, so presumably there’s some under-the-hood caching magic being attempted there.
I think I am having trouble getting the addressables from firebase to to the right spot. Unless I am missing something, should my addressables downloads be in the cache and not the data to initialize?
Since the Addressables Firebase Storage plugin uses normal Addressables APIs there is no custom saving location or something. Please check the Addressable documentation/settings for the save location. But, yes. I think it should be saved in the Cache. Although it would also be possible to be in Data which is not cleared by the OS when storage gets short.
You can use
Debug.Log($"Current cache: {Caching.defaultCache.path}");
var cachePaths = new List<string>();
Caching.GetAllCachePaths(cachePaths);
foreach (var cachePath in cachePaths)
{
Debug.Log($"Cache path: {cachePath}");
}
To find out the caching paths on your system/OS/Device and check them with adb/itunes/etc.
I’ve tried this package and that worked great for me. Caching works fine as well. The only thing I want to mention is the lost internet connection on the device (I use the catalog in addressables). In that case, the tool should use the local cache, but it doesn’t. I’ve tried to workaround that using the saved hash string (link below), but it’s not so simple and needs more time to understand how to modify the code. Any help?