User accounts

A user represents an identity within the server. Every user is registered and has a profile for other users to find and become friends with or join groups and chat.

A user can own records, share public information with other users, and login via a bunch of different social providers.

Fetch self

When a user has a session you can retrieve their profile. The profile is returned for yourself and so we refer to it as "self" in client code. The profile contains lots of information which includes various "linked" social providers.

var message = NSelfFetchMessage.Default();
client.Send(message, (INSelf self) => {
  Debug.LogFormat("User has id '{0}' and handle '{1}'.", self.Id, self.Handle);
  Debug.LogFormat("User has JSON metadata '{0}'.", self.Metadata);
}, (INError err) => {
  Debug.LogErrorFormat("Error: code '{0}' with '{1}'.", err.Code, err.Message);
});
CollatedMessage<Self> message = SelfFetchMessage.Builder.build();
Deferred<Self> deferred = client.send(message);
deferred.addCallback(new Callback<Self, Self>() {
  @Override
  public Self call(Self self) throws Exception {
    String metadata = new String(self.getMetadata());
    System.out.format("User has JSON metadata '%s'.", metadata);
    return self;
  }
}).addErrback(new Callback<Error, Error>() {
  @Override
  public Error call(Error err) throws Exception {
    System.err.format("Error('%s', '%s')", err.getCode(), err.getMessage());
    return err;
  }
});
let message = SelfFetchMessage()
client.send(message: message).then { selfuser in
  NSLog("User id '%@' and handle '%@'", selfuser.id, selfuser.handle)
  NSLog("User has JSON metadata '%@'", selfuser.metadata)
}.catch { err in
  NSLog("Error %@ : %@", err, (err as! NakamaError).message)
}
var message = new nakamajs.SelfFetchRequest();
client.send(message).then(function(result) {
  console.log("User id '%o' and handle '%o'.", result.self.id, result.self.handle);
  console.log("User has JSON metadata: %o", result.self.metadata);
}).catch(function(error){
  console.log("An error occured: %o", error);
})

Some information like social IDs are private but part of the profile is visible to other users.

Public field Description
AvatarUrl A URL with a profile picture for the user (empty by default).
CreatedAt A timestamp in milliseconds for when the user was created.
Fullname The full name for the user (empty by default).
Handle A unique nickname for the user.
Id The unique identifier for the user.
Lang The preferred language settings for the user (default is "en").
LastOnlineAt A timestamp in milliseconds when the user was last online.
Location The location of the user (empty by default).
Metadata A slot for custom information to be added for the user (must be JSON encoded).
Timezone The timezone of the user (empty by default).
UpdatedAt A timestamp in milliseconds for when the user was last updated.

You can store additional fields for a user in "Metadata" which is useful to share data you want to be public to other users. Metadata is limited to 16KB per user.

Tip

We recommend you choose user metadata to store very common fields which other users will need to see. For all other information you can store records with public read permissions which other users can find.

Fetch users

You can fetch one or more users by their IDs or handles. This is useful for displaying public profiles with other users.

string id = user.Id; // an INUser ID.

var message = NUsersFetchMessage.Default(id);
client.Send(message, (INResultSet<INUser> list) => {
  Debug.LogFormat("Fetched '{0}' users.", list.Results.Count);
  foreach (var user in list.Results) {
    Debug.LogFormat("User has id '{0}' and handle '{1}'.", user.Id, user.Handle);
  }
}, (INError err) => {
  Debug.LogErrorFormat("Error: code '{0}' with '{1}'.", err.Code, err.Message);
});
byte[] id = user.getId(); // a User object Id.

CollatedMessage<ResultSet<User>> message = UsersFetchMessage.Builder.newBuilder()
  .id(id)
  .build();
Deferred<ResultSet<User>> deferred = client.send(message);
deferred.addCallback(new Callback<ResultSet<User>, ResultSet<User>>() {
  @Override
  public ResultSet<User> call(ResultSet<User> list) throws Exception {
    for (User user : list) {
      String userId = new String(user.getId());
      System.out.format("User(id=%s, handle=%s)", userId, user.getHandle());
    }
    return self;
  }
}).addErrback(new Callback<Error, Error>() {
  @Override
  public Error call(Error err) throws Exception {
    System.err.format("Error('%s', '%s')", err.getCode(), err.getMessage());
    return err;
  }
});
let userID // a User ID

var message = UsersFetchMessage()
message.userIDs.append(userID)

client.send(message: message).then { users in
  for user in users {
    NSLog("User id '%@' and handle '%@'", user.id, user.handle)
  }
}.catch { err in
  NSLog("Error %@ : %@", err, (err as! NakamaError).message)
}
string userId = "" // a User ID

var message = new nakamajs.UsersFetchRequest();
message.userIds.push(userId);

client.send(message).then(function(result) {
  result.users.foreach(function(user){
    console.log("User id '%o' and handle '%o'.", user.id, user.handle);
  });
}).catch(function(error){
  console.log("An error occured: %o", error);
})

You can also fetch one or more users in server-side code.

local nk = require("nakama")

local user_ids = {
  "3ea5608a-43c3-11e7-90f9-7b9397165f34",
  "447524be-43c3-11e7-af09-3f7172f05936"
}
local users = nk.users_fetch_id(user_ids)
for _, u in ipairs(users)
do
  local message = ("handle: %q, fullname: %q"):format(u.Handle, u.Fullname)
  nk.logger_info(message)
end

Update self

When a user is registered most of their profile is setup with default values. A user can update their own profile to change fields but cannot change any other user's profile.

var message = new NSelfUpdateMessage.Builder()
    .AvatarUrl("http://graph.facebook.com/avatar_url")
    .Fullname("My New Name")
    .Location("San Francisco")
    .Build();
client.Send(message, (bool done) => {
  Debug.Log("Successfully updated yourself.");
}, (INError err) => {
  Debug.LogErrorFormat("Error: code '{0}' with '{1}'.", err.Code, err.Message);
});
CollatedMessage<Boolean> message = SelfUpdateMessage.Builder.newBuilder()
    .avatarUrl("http://graph.facebook.com/avatar_url")
    .fullname("My New Name")
    .location("San Francisco")
    .build();
Deferred<Boolean> deferred = client.send(message);
deferred.addCallback(new Callback<Boolean, Boolean>() {
  @Override
  public Boolean call(Boolean done) throws Exception {
    System.out.println("Successfully updated yourself.");
    return done;
  }
}).addErrback(new Callback<Error, Error>() {
  @Override
  public Error call(Error err) throws Exception {
    System.err.format("Error('%s', '%s')", err.getCode(), err.getMessage());
    return err;
  }
});
var message = SelfUpdateMessage()
message.avatarUrl = "http://graph.facebook.com/avatar_url"
message.fullname = "My New Name"
message.location = "San Francisco"
client.send(message: message).then {
  NSLog("Successfully updated yourself.")
}.catch { err in
  NSLog("Error %@ : %@", err, (err as! NakamaError).message)
}
var message = new nakamajs.SelfUpdateRequest();
message.avatarUrl = "http://graph.facebook.com/avatar_url"
message.fullname = "My New Name"
message.location = "San Francisco"

client.send(message).then(function() {
  console.log("Successfully updated yourself.");
}).catch(function(error){
  console.log("An error occured: %o", error);
})

With server-side code it's possible to update one or more user's profiles.

local nk = require("nakama")

local user_update = {
  UserId = "4ec4f126-3f9d-11e7-84ef-b7c182b36521", -- some user's id.
  AvatarUrl = "http://graph.facebook.com/avatar_url",
  Fullname = "My new Name",
  Location = "San Francisco",
  Metadata = {}
}
local status, err = pcall(nk.users_update, { user_update })
if (not status) then
  nk.logger_info(("User update error: %q"):format(err))
end