[Unity SDK - Android] Couldn't determine a writable folder where to store realm file

Hi,

I am getting the InvalidOperationException: ‘couldn’t determine a writable folder where to store realm file’.

I am creating a Unity game, using the Unity SDK for Realm, where I am building it for Android and IOS. The error occurs building it onto my Samsung S8, whilst the Unity editor works perfectly fine, saving into locallow, and IOS I have yet to test.

I have tried multiple combinations of the functions Realm realm = Realm.GetInstance(), with and without parameters, along with the addition of a RealmConfiguration, also with and without taking parameters. Application.persistentDataPath, Environment.GetFolderPath(Environment.SpecialFolder.Personal), RealmConfiguration.DefaultConfiguration.DatabasePath, leaving it blank and various other paths I have tried have all failed to work, all giving the same error.

I am finding it quite weird how this error seems to be nearly non existent on the internet other than two github issues which haven’t helped at all. Does anyone have any suggestions of what could be causing this?

Thanks

Hi Ben,

Unfortunately without seeing no code at all, it’s very hard for me to understand why you’re seeing what you’re seeing. I made a quick test project in Unity 2021.1.13f1 using Realm 10.2.1 and I hit no issues.
Could you share what version of Unity you’re using, which Operating System and which version of Realm?
Additionally could you post as much code as you think it’s reasonable? I assume it’s a test project just started, so it shouldn’t be a problem. But if I’m wrong I can supply you with a link to securely update your whole project.

1 Like

Hi, after reading this, I created a test project to showcase only the realm code that was not working, which lead me to find the issue that I am facing. Changing the scripting backend of the project in Unity from Mono to IL2CPP is what is causing it, which seems to involve the use of C# Reflection. As we are planning to publish to the google play store, IL2CPP looks to be something that we will need. Is there anything that we can do to get around this?

I am using Unity 2021.1.3f1 and Realm 10.2.0, with Windows 10

I greatly appreciate the response, thank you

Test project code if it is still any use:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Realms;

public class GameInitialiser : MonoBehaviour
{

    private Realm realm;
    private SaveModel saveModel;

    void Start()
    {
        RealmConfiguration config = new RealmConfiguration();
        realm = Realm.GetInstance(config);
        Debug.Log(config.DatabasePath);

        string saveName = "exampleName";
        saveModel = realm.Find<SaveModel>(saveName);
    }

    private void OnDisable()
    {
        realm.Dispose();
    }
}

Test RealmObject:

public class SaveModel : RealmObject
{
    [PrimaryKey]
    public string saveName { get; set; }

    public SaveModel(string saveName)
    {
        this.saveName = saveName;
    }

    public SaveModel()
    {
    }
}

I’m glad to hear that slowly we’re getting toward a solution. Unfortunately, the example you posted doesn’t show me the usage you make of reflection. But yes, what you are mentioning is a known problem:
When converting IL, IL2CPP strips as much as possible. When you use reflection, IL2CPP can’t understand what that piece of code is actually going to “refer to/do”. So, for example, if the only reference to a certain type in your project is made through reflection (for example dynamic instance creation of that type) IL2CPP won’t include that type in the final binary and you’ll clearly have issues.
However, not all is lost. You can, in fact, suggest IL2CPP that certain things (like types or properties) should not be stripped. This can be done through the preserve attribute. You can read more about all I said in our official documentation.

I hope this helps. If you still run into problems, even after hinting IL2CPP which types and properties to additionally include, don’t hesitate to let me know.

2 Likes

Thank you very much! I have learnt a lot from this

For anyone else reading, the solution for my current project was to create a link.xml file in the assets folder of the unity project to specify what to preserve, where I have chosen to preserve the full assemblies for Realm and Realm.UnityUtils; the two .dll assemblies I could find that I was using for Realm. - However this method of preserving is one of many, just this seems to suit my project the best so far.

<linker>
	<assembly fullname="Realm.UnityUtils" preserve="all"/>
	<assembly fullname="Realm" preserve="all"/>	
</linker>

A helpful link found through the official documentation hyperlink above: Managed Code Stripping

Hi Ben.
The SDK for Unity is a new product, so there’s could be a few issues here and there. Regardless, I’m surprised that you need to add Realm and Realm.UnityUtils to link.xml.
The error you reported

InvalidOperationException: ‘couldn’t determine a writable folder where to store realm file’.

is given by android apps not being able to write everywhere in the filesystem. To fix this issue we set the right path for the app at initialization time. This is done in Realm.UnityUtils which is referenced through reflection, so it makes sense that if not included (stripped) the operation results with the message you showed. The thing is that we do use the attribute [Preserve] in the entry method of Realm.UnityUtils, so that should not be stripped, but you seem to suggest otherwise.
To help us understand better why this is happening, could you share what settings and compiler arguments you use for your builds? I tried myself even with the highest stripping setting for IL2CPP and it’s still working just fine. So maybe you have changed more settings, and I’d like to replicate that to understand what’s happening.

Settings for Android/Other Settings should be the interesting section, unless you have more interesting setting fields. Screenshots of the settings should do, unless you have sensible data there. In that case I’ll supply you with a link for securely uploading the screenshots.

Thank you in advance for the cooperation.

Andrea

1 Like

Hi, after testing more with the link xml file, I can confirm that I only get the InvalidOperationException when Realm.UnityUtils is not being preserved, where removing the line to preserve Realm did not cause any issues.

From my knowledge we have not changed these settings much at all, or set any special compiler arguments.

These are the build settings I am using to create a dev build:
image

Unity Other Settings:


This is the basis of the singleton class where Realm starts in my code and doesn’t get past RealmConfiguration config = new RealmConfiguration();.

 private Realm realm;
 [SerializeField] GameObject ____;

    private void Start()
    {
        RealmConfiguration config = new RealmConfiguration();
        realm = Realm.GetInstance(config);
        ...

If you need anything else just let me know,

Thanks

1 Like

Hi Ben,

You are right. You build settings are pretty much the default ones, matching mine.

This is the basis of the singleton class where Realm starts in my code and doesn’t get past RealmConfiguration config = new RealmConfiguration();

Are you saying that that’s the line that gives you that error? I’d expect the one below. Is there a stack trace that you could post? That’d be helpful.

Out of curiosity, could you try updating to the latest Realm version (10.3.0). Just to remove “the typical suspects” from the equation. Let’s see if any difference appears.

I wanted to say that your contribution is truly appreciated! And I’m totally happy that you can at least proceed with your work while we try to remove these edge cases.

Andrea

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.