question

ebrahimB avatar image
ebrahimB asked

Trouble logging in with Java SDK

I recently integrated the Java SDK into my project but have been running into an issue when I try to login. Here is the code I use to Login:


PlayFabSettings.TitleId = GameConstants.PLAYFAB_TITLE;
//Login to playfab
LoginWithCustomIDRequest request = new LoginWithCustomIDRequest();
request.CustomId = customUserID;
request.CreateAccount = true;
request.TitleId = GameConstants.PLAYFAB_TITLE;
PlayFabResult<LoginResult> result = PlayFabClientAPI.LoginWithCustomID(request);

 

I get the following error: "Failed to post to server: https://XXXX.playfabapi.com/Client/LoginWithCustomID"

The ID(XXXX) in the URL is correct but I still get that error.

I tried posting directly with the same settings and it worked. So either I did something wrong using the Java SDK or there may be an issue with the SDK. It is probably the former but I just want to make sure.

 

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1807605288 avatar image 1807605288 ♦ commented ·

The issue you are seeing comes from here:

https://github.com/PlayFab/JavaSDK/blob/master/AndroidStudioExample/app/src/main/java/com/playfab/internal/PlayFabHTTP.java#L59

This is an error in the Java HTTPS module, outside of our control. Unfortunately we're hiding the exception information. Please debug or print the information from that "e" exception object to debug the specific issue you're seeing.

We will add more information to the error report so people who experience this issue in the future don't have to repeat your work.

0 Likes 0 ·
brendan avatar image
brendan answered

That would mean that there's an exception being thrown when calling the stream writer. Since we test the SDKs locally on each update, I can assure you that the Login calls do actually work. The most likely explanation is that something is blocking the stream writer, such as a lack of internet connection or a firewall. Can you check your local setup to confirm? What is the device making the call?

4 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

ebrahimB avatar image ebrahimB commented ·

I can confirm that I am connected to the internet. I am running the app from bluestacks, an Android emulator that runs on my PC. 

0 Likes 0 ·
brendan avatar image brendan commented ·

Can you get a Wireshark or Netmon capture, to see what the actual details of the network traffic are?

0 Likes 0 ·
Evan avatar image Evan commented ·

Was having a similar problem, and after stepping into the SDK code I found the doPostPrivate method was getting an 'android.os.NetworkOnMainThreadException'.

Might be helpful to make this case more visible to users who are testing out the API in their onCreate method like I was ;)

0 Likes 0 ·
brendan avatar image brendan Evan commented ·

We'll be posting some more detailed guides on getting started developing for PlayFab on various platforms as soon as we can, to help developers avoid issues like this. The NetworkOnMainThreadException specifically is saying "you can't make a network call on the main user interface thread". This was introduced back with the Ice Cream Sandwich release, to protect the UI from a potentially expensive operation. I just spoke with a member of the tools team about this, and he'll post a follow-up shortly with a snippet showing how to do this correctly.

0 Likes 0 ·
1807605288 avatar image
1807605288 answered

Evan:

We are in-progress on writing a Getting Started Guide for the Java SDK.

I can't link to it yet, because it's in review, but I can share the code sample:

import java.util.concurrent.*;
import java.util.*;

import com.playfab.PlayFabErrors.*;
import com.playfab.PlayFabSettings;
import com.playfab.PlayFabClientModels;
import com.playfab.PlayFabClientAPI;

public class GettingStarted
{
    private static boolean _running = true;

    public static void main(String[] args) {
        PlayFabSettings.TitleId = "144";

        PlayFabClientModels.LoginWithCustomIDRequest request = new PlayFabClientModels.LoginWithCustomIDRequest();
        request.CustomId = "GettingStartedGuide";
        request.CreateAccount = true;

        FutureTask<PlayFabResult<com.playfab.PlayFabClientModels.LoginResult>> loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
        loginTask.run();

        while (_running) {
            if (loginTask.isDone()) { // You would probably want a more sophisticated way of tracking pending async API calls in a real game
                OnLoginComplete(loginTask);
            }

            // Presumably this would be your main game loop, doing other things
            try {
                Thread.sleep(1);
            } catch(Exception e) {
                System.out.println("Critical error in the example main loop: " + e);
            }
        }
    }

    private static void OnLoginComplete(FutureTask<PlayFabResult<com.playfab.PlayFabClientModels.LoginResult>> loginTask) {
        PlayFabResult<com.playfab.PlayFabClientModels.LoginResult> result = null;
        try {
            result = loginTask.get(); // Wait for the result from the async call
        } catch(Exception e) {
            System.out.println("Exception in PlayFab api call: " + e); // Did you assign your PlayFabSettings.TitleId correctly?
        }

        if (result != null && result.Result != null) {
            System.out.println("Congratulations, you made your first successful API call!");
        } else if (result != null && result.Error != null) {
            System.out.println("Something went wrong with your first API call.");
            System.out.println("Here's some debug information:");
            System.out.println(CompileErrorsFromResult(result));
        }

        _running = false; // Because this is just an example, successful login triggers the end of the program
    }

    // This is a utility function we haven't put into the core SDK yet.  Feel free to use it.
    private static <RT> String CompileErrorsFromResult(PlayFabResult<RT> result) {
        if (result == null || result.Error == null)
            return null;

        String errorMessage = "";
        if (result.Error.errorMessage != null)
            errorMessage += result.Error.errorMessage;
        if (result.Error.errorDetails != null)
            for (Map.Entry<String, List<String>> pair : result.Error.errorDetails.entrySet() )
                for (String msg : pair.getValue())
                    errorMessage += "\n" + pair.getKey() + ": " + msg;
        return errorMessage;
    }
}

The example code kicks off the api call in a thread, saves a reference to the FutureTask instance, and calls isDone() on it periodically until the threaded call is complete.
You SHOULD ABSOLUTELY NOT cause any of the API call work to happen on the main thread as it'll possibly throw an exception, or otherwise it'll definitely lock up your program until the API call completes.

The new Getting Started Guides will contain this code once they're published, but this is a sneak peek of the code.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.