Search Unity

Device not caching addressable assets

Discussion in 'Addressables' started by DanMcElroyHuuuge, Oct 14, 2019.

  1. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Hi all,

    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!

    Group Settings:
    upload_2019-10-14_13-3-27.png

    AddressableAssetsSettings:
    upload_2019-10-14_13-5-17.png

    CacheInitializationSettings
    upload_2019-10-14_13-5-43.png
     
  2. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Does firebase change the URL in any way? AFAIK caching identifies bundles by checking the last 'segment' of the url.
     
  3. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    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.

    I'm using the very helpful Firebase Storage with Addressables library from @robinryf: https://gitlab.com/robinbird-studio...rebase-tools/tree/master/Storage/Addressables

    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.
     
  4. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Can you show me an example of an endpoint?
     
  5. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Sure thing!

    The actual download URL for the file is:

    https://firebasestorage.googleapis....ia&token=11781671-8b9f-4262-87c2-778c68cc14f5

    Where that token appears to be constant.

    However, the RemoteLoadPath is configured as:

    gs://accountname.appspot.com/Addressables/[BuildTarget]

    so what it's actually trying to resolve is something like:

    gs://accountname.appspot.com/Addressables/Android/bundlename.bundle

    Which is then converted by the selected `FirebaseAssetBundleProvider` into the proper HTTPS download URL above.
     
  6. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    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.
     
    Last edited: Oct 14, 2019
  7. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Last edited: Oct 14, 2019
  8. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    Can you verify loading assetbundles to cache outside of the addressables environment works as expected?

    Just attach below script, this works on my end:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class AssetBundleDownloader : MonoBehaviour
    7. {
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.         Caching.ClearCache();
    12.         StartCoroutine(DownloadBundle("https://s3-eu-west-1.amazonaws.com/nils.mysmilez.nl/Android/packedassets_assets_assets/vrworlds/loft/loftvr.prefab_2cf8877c87095e8687e16fe0d13d105f.bundle"));
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update()
    17.     {
    18.        
    19.     }
    20.  
    21.     IEnumerator DownloadBundle(string link)
    22.     {
    23.         UnityWebRequest download = UnityWebRequestAssetBundle.GetAssetBundle(link + "?statictoken=123", Hash128.Parse("123456789"));
    24.  
    25.         download.SendWebRequest();
    26.  
    27.         while(!download.isDone)
    28.         {
    29.             Debug.Log(download.downloadProgress);
    30.             yield return null;
    31.         }
    32.  
    33.         if(!(download.isNetworkError || download.isHttpError))
    34.         {
    35.             Debug.Log("First download is done, this one should have taken quite a long time");
    36.             //bundle should now be cached
    37.  
    38.             if(Caching.IsVersionCached(link  + "?statictoken=456&extraparam=hello", Hash128.Parse("123456789")))
    39.             {
    40.                 UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle("https://s3-eu-west-1.amazonaws.com/beng.mysmilez.nl/content/loftvr.prefab_2cf8877c87095e8687e16fe0d13d105f.bundle" + "?statictoken=456", Hash128.Parse("123456789"));
    41.                 request.SendWebRequest();
    42.  
    43.                 while(!request.isDone)
    44.                 {
    45.                     Debug.Log(request.downloadProgress);
    46.                     yield return null;
    47.                 }
    48.  
    49.                 if(!(request.isNetworkError || request.isHttpError))
    50.                 {
    51.                     Debug.Log("Second download is done, this one should have finished immediately");
    52.                 }
    53.             }
    54.                
    55.             else
    56.                 Debug.LogError("bundle is not cached");
    57.         }
    58.     }
    59. }
    60.  
     
  9. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Trying that now. Thanks again for the support!
     
  10. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Can confirm, worked as expected - long first download, instant second.
     
  11. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
  12. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    1. If I run it a second time, the cache seems to persist.
    2. 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.
     
  13. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    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.
     
    Last edited: Oct 15, 2019
  14. robinryf

    robinryf

    Joined:
    May 22, 2014
    Posts:
    54
    Favo-Yang likes this.
  15. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Perfect, thanks for reacting so quickly! I'm testing it out now and will let you know ASAP.
     
  16. DanMcElroyHuuuge

    DanMcElroyHuuuge

    Joined:
    Oct 2, 2019
    Posts:
    18
    Can confirm, works great!
     
  17. stevenchristian20

    stevenchristian20

    Joined:
    Dec 23, 2019
    Posts:
    29
    Hey @robinryf ,

    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?

     

    Attached Files:

  18. robinryf

    robinryf

    Joined:
    May 22, 2014
    Posts:
    54
    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
    Code (CSharp):
    1. Debug.Log($"Current cache: {Caching.defaultCache.path}");
    2.  
    3. var cachePaths = new List<string>();
    4. Caching.GetAllCachePaths(cachePaths);
    5. foreach (var cachePath in cachePaths)
    6. {
    7.      Debug.Log($"Cache path: {cachePath}");
    8. }
    9.  
    To find out the caching paths on your system/OS/Device and check them with adb/itunes/etc.
     
    stevenchristian20 likes this.
  19. stevenchristian20

    stevenchristian20

    Joined:
    Dec 23, 2019
    Posts:
    29
    awesome thankz.
     
  20. Mortalyx

    Mortalyx

    Joined:
    Mar 20, 2015
    Posts:
    7
    Hi everyone!

    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?

    https://share.getcloudapp.com/QwulXv4P
     
  21. robinryf

    robinryf

    Joined:
    May 22, 2014
    Posts:
    54
  22. javierfed

    javierfed

    Joined:
    Apr 10, 2015
    Posts:
    50
    I used the code in this post to find the caching location, and viewing said location I only see the hash and the json file, it does not contain the bundle, but my application does pull the content, as firebase usage is showing the full amount downloaded... this happens even on my mobile devices. is there anyway to test and find out where the caching is going wrong? maybe a setting or something I may have missed?