nk.accountUpdateId TypeError: expects string

When updating the metadata I get this “TypeError: expects string”

function rpcUpdateMetadata(context: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, metadata: string): void {
    const metadataObj = JSON.parse(metadata);
    let displayName: string = metadataObj["DisplayName"];
    let avatarID: string = metadataObj["AvatarID"];

    logger.info('rpcUpdateMetadata DisplayName ' + displayName + " AvatarID " + avatarID);
    try {
        nk.accountUpdateId(context.userId, null, displayName, null, null, null, avatarID, {
            DisplayName: displayName,
            AvatarID: avatarID
        });
    } catch (error) {
        logger.error('rpcUpdateMetadata Writing metadata failed' + error);

    }
}

Shared the code. Please point out what I am doing wrong!

adding the same items to metadata to test it. but not able to get this to work.

Hey @Sathyaraj you haven’t shared the line number of the error or the value of metadata when the RPC is invoked, but I’d guess based on the information you supplied that metadata is null or undefined. Otherwise I suggest narrowing down your code and improving your logging to isolate the issue.

Error is thrown in try-catch block.Metadata is defined in-line
{
DisplayName: displayName,
AvatarID: avatarID
}

Please provide the full error

I suspect the error comes from the userId being undefined, if you’re invoking this RPC from a S2S call the userId is not defined in the context - but this is just a guess.

This is the error

"msg":"rpcUpdateMetadata Writing metadata failedTypeError: expects string","rpc_id":"rpc_update_metadata"}

If I print the used it prints a valid id

"msg":"rpcUpdateMetadata DisplayName screax AvatarID 1 userId 0ba3d0b0-365d-4d34-9b3b-6a95daef9abb","rpc_id":"rpc_update_metadata"}

If you’re not on the latest server version please upgrade to latest.

If that doesn’t resolve the issue please provide a minimal InitModule example to reproduce the error.

I am on 3.19.0
Here is the code

function InitModule(_ctx: nkruntime.Context, logger: nkruntime.Logger, _nk: nkruntime.Nakama, initializer: nkruntime.Initializer) {
    logger.info("Hello World!..............................");

    initializer.registerRpc("rpc_update_metadata", rpcUpdateMetadata);
    logger.info('JavaScript logic loaded.');
}

function rpcUpdateMetadata(context: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, metadata: string): void {
    const metadataObj = JSON.parse(metadata);
    let displayName: string = metadataObj["DisplayName"];
    let avatarID: string = metadataObj["AvatarID"];

    logger.info('rpcUpdateMetadata DisplayName ' + displayName + " AvatarID " + avatarID + " userId " +context.userId);
    try {
        nk.accountUpdateId(context.userId, null, displayName, null, null, null, avatarID, {
            DisplayName: displayName,
            AvatarID: avatarID
        });
    } catch (error) {
        logger.error('rpcUpdateMetadata Writing metadata failed' + error);

    }
}

From Unity calling as follows

 var playerMetaData = new PlayerMetadata
{
    DisplayName = PlayerPreference.playerName,
    AvatarID = PlayerPreference.avatarIndex
};

var jsonString = JsonConvert.SerializeObject(playerMetaData);
 
_socket.RpcAsync("rpc_update_metadata", jsonString);

Invoking this function with payload:

{
    "DisplayName": "some_player_name",
    "AvatarID": "some_avatar_url"
}

worked without issue, your problem is likely in the serialization of the JSON in the your client code.

Okay this one worked.

function rpcUpdateMetadata(context: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, metadata: string): void {
    const metadataObj = JSON.parse(metadata);
    let displayName: string = metadataObj["DisplayName"];
    let avatarID: string = metadataObj["AvatarID"];

    logger.info('rpcUpdateMetadata DisplayName ' + displayName + " AvatarID " + avatarID + " userId " +context.userId);
    try {
        nk.accountUpdateId(context.userId, null, displayName.toString(), null, null, null, avatarID.toString(), {
            DisplayName: displayName,
            AvatarID: avatarID
        });
    } catch (error) {
        logger.error('rpcUpdateMetadata Writing metadata failed' + error);
    }
}

Had to change the displayName and avatarID to displayName.toString() and avatarID.toString()
Not sure why it works that way even if the variable is statically typed

 let displayName: string = metadataObj["DisplayName"];
 let avatarID: string = metadataObj["AvatarID"];