Session restore null in godot

Hi all, I’m trying to use the sessian.restore method to jump a previously logged user right into the game.
However the method returns null, as it should since session is really null. What am I missing here?

The docs state that:

Restore a session without having to re-authenticate:

1 var auth_token = "restored from save location"
2 var refresh_token = "restored from save location"
3 session = session.restore(auth_token, refresh_token)

And the github docs state that:

var authtoken = "restored from somewhere"
var session2 = NakamaClient.restore_session(authtoken)
	if session2.expired:
		print("Session has expired. Must reauthenticate!")

So, in my code, having already saved previously tokens:

var client : NakamaClient
var session : NakamaSession

var auth_token = "user://Nakama/auth.save"
var refresh_token = "user://Nakama/refresh.save"

func _ready():
	client = Nakama.create_client(
			nakama_server_key,
			nakama_host,
			nakama_port,
			nakama_scheme,
			Nakama.DEFAULT_TIMEOUT,
			NakamaLogger.LOG_LEVEL.ERROR)

func check_session_restore():
	if auth_token == null or refresh_token == null:
		pass
	else:
        #Here I'm testing the doc version:
		session = session.restore(auth_token, refresh_token)
        #This is a version from the github docs:
		var session2 = NakamaClient.restore_session(auth_token)
		if session2.is_exception():
			print("An error occurred: %s" % session2)
			return

The Nakama site’s doc’s output is as follow:

Invalid Call. Nonexistent function 'restore' in base 'Nil'
Basically, session is null.

And the github’s error is as follow:
An error occurred: NakamaException(StatusCode={-1}, Message='{Unable to unpack token: user://Nakama/auth.save}', GrpcStatusCode={-1})

I can see that my first session var is null, should be since I didn’t call anything on it yet. But how am I going to make it not null then? The client is already created, how can I populate this session before calling restore? Sorry if I was caught in the translation, since my native language is not english, but from the docs I could not understand where to go to.

EDIT:
Ok I solved it by adding:

session = yield(client.authenticate_device_async(device_id), "completed")

I link the user’s device upon registration. But there is an error, it says there is NO function “restore” in session. So are the docs mistaken?
The docs that state to use session.restore is here:
Nakama: Godot | Heroic Labs Documentation

Hi @luiscesjr,

Firstly, you are right in that the documentation appears to be incorrect. The correct usage, as per the GitHub repo, is:

var session = NakamaClient.restore_session(auth_token)

We will get this resolved ASAP, thank you for bringing this to our attention.

Secondly, it looks like you are passing the raw string "user://Nakama/auth.save" as the token, rather than the contents of that file. Did you mean to read the contents instead? If so, you can do:

var file = File.new()
file.open("user://Nakama/auth.save", File.READ)
var auth_token = file.get_as_text()
file.close()

Finally, your solution of re-authenticating will get your users back into the game but is not quite the same as restoring a previously authenticated session. If you are ok with the user getting a brand new session token every time then this is a perfectly viable solution.

As a side note, the benefit of restoring a session vs re-authenticating is that the user will not have to go through any potential UI/UX login flow. If your game is using device authentication this may not effect your users, but in general it is a good idea to restore vs re-authenticate where possible to get your players straight back into the game as quickly and smoothly as possible.

Kind regards,
Tom

1 Like

Thank you! I’ve seen something else different, but I don’t remember. If I spot it again, who should I contact about it?

Oh, I didn’t put here, but I do open it. HOWEVER :slight_smile: , I was not assigning it to a different var.

func load_auths():
	var file = File.new()
	if file.file_exists(auth_token):
		file.open(auth_token, File.READ)
		auth_token_loaded = file.get_var() #I was assiging auth_token itself here, it was probbaly confusing the engine, should work nonetheless, but wasn't.
		file.close()

It does work now! Thank you. But there is still this question:
(As you stated:)

I guess, you mean because of session expiring? And so user’s themselves should re-authenticate? It makes sense, I’m sorry I’m new to this “side” of programming, and I’m still learning the best practices.
And so, how should I better approach this?

Like, if the user is still in their “auth expiry window”, then they should not need to re-authenticate, and get back into the game, else, prompt the user about their expiration and send them back to the login page. (Writing this down made it a bit more clear in my mind, should I check if the token is expired and use the same restore method if it’s not expired?)

I’m glad you were able to get it working. :slight_smile:

Thank you! I’ve seen something else different, but I don’t remember. If I spot it again, who should I contact about it?

Please make a post here on the forum under the Documentation section and we’ll resolve the issue as soon as we can.

I guess, you mean because of session expiring? And so user’s themselves should re-authenticate? It makes sense, I’m sorry I’m new to this “side” of programming, and I’m still learning the best practices.
And so, how should I better approach this?

No problem at all. I would recommend taking a look at the Session Management section of our documentation and, more specifically, the How a session ends section which details the best practice for session refreshing/restoration and re-authentication.

I hope this helps.

Kind regards,
Tom

1 Like