Trouble using storage_write in Lua

Hello again,
I’m trying to write some data from the server to the database. I’m using a RPC call in Godot to call the function. Everything is working fine except the “nakama.storage_write()”

This is the error that I recive from the failed RPC call:

=== Nakama : DEBUG === Request 4 returned response code: 500, RPC code: 13, error: {"Type":2,"Object":"/nakama/data/modules/user_seed_generator.lua:37: bad argument #1 to storage_write (expects user_id to be a valid ID)",

The code in the server-side is:

function save_seed(context, userid)
    local seed = generate_user_seed() -- Generates a random string
    local database_payload = {{collection = "daily_seed", key="seed", user_id = userid, {seed}}} -- [ !!! ]
    nakama.storage_write(database_payload )
end

My problem right know is understanding the format of the table that the storage_write function is expecting. I’ve looked at the docs but I couldn’t find in any entry with “storage_write” or it’s proper page on fuction reference a hint about that (It might be easier that it seems and I’m either just completely blind or I’m a noobie and I haven’t figured it out). As you can see I even double braced the table just because I saw an example on the github sample project do something similar.


Independently, and I don’t know if I should start a topic just for what I’m going to say. I was thinking about a Nakama users discord. The forum is great as it is. But I thought I had nowhere to ask quick questions about nakama, and some of them might just be really simple and making a topic out of it might be an overkill. I don’t know if I’m the only one with this suggestion.

Hey @MaximoTG98.

It looks like the userid you’re passing in isn’t valid. Can you check that you’re passing the correct argument to your save_seed function.

You can also check out this example for how to use the storage_write function in Lua.

2 Likes

Okey I got it working! My problem was the syntax of a lua table? (and my understanding of it)
I’m going to write my problems and how I solved it just in case someone finds this topic. (In a very beguinner friendly manner, because that’s who I am) (I will be adding ‘?’ were I’m not sure, please if you know how to improve this post just let me know and I will edit it, but also check if there are other comments below since there are chances I’m not explaning something right)

the storage_write function takes a dictionary/table argument that contains:

  • collection: string, key:string - points to the database

  • permission_read:int ,permission_write:int - As found on the docs both of them are expected to describe the permissions of that object

  • version:string ? - Can be omitted and nakama will assing a value, preferible you want to manage it to avoid concurrent writes

  • user_id: string - In the case that you are using a RPC call, that rpc call from the client to the server will also carry a context table/dictionary, which has the user_id of the user that sent the rpc call. And the user has to exist before you write something on it’s storage.

  • value: dictionary/table ? - This one is the one that I understand the least, but I think my problem is more related to my Lua knowladge than it’s proper syntax. You can pass a dictionary with as many keys with it’s values you want. For lua a dictionary variable is declared with {}, and inside, each key is created with [“key_name”] = value ?. Example:
    {[“gold”] = gold_ammount,[“reputation”] = user_reputation}

I hope this helps!

2 Likes

@MaximoTG98 Just to complete your knowledge I’ve replied to a few of your open questions.

version:string ? - Can be omitted and nakama will assing a value, preferible you want to manage it to avoid concurrent writes

Yes, the server assigns a version to a storage object so it can be updated conditionally if that version is used after a read of the storage object. If you don’t care about the conditional update flow you can omit the version field and it will overwrite whatever is stored without the check.

value: dictionary/table ? - This one is the one that I understand the least, but I think my problem is more related to my Lua knowladge than it’s proper syntax.

Yes, in Lua there’s table arrays:

local arr = { "foo", "bar" }

And there’s tables:

local tbl = {
    foo = "some",
    bar = "value"
}

The data type in Lua is flexible enough to represent both maps and arrays. This is unusual compared to almost all other programming languages that have separate syntax and types to represent these two data types.

Back to the "value" field of the storage write. The value can be a Lua table (map) which can contain as nested a structure as you like and it will be written to the storage engine as a JSON object.

Hope this clears up any confusion.