How to configure OnlineSubsystem LoginFlow

Hey Everyone!

I’m stuck with the new Online Subsystem implementation in 4.16.1 for facebook and google. Login is not working by default. I am getting as far as FOnlineExternalUIFacebook::ShowLoginUI which attempts to trigger a delegate:

TriggerOnLoginFlowUIRequiredDelegates(RequestedURL, OnRedirectURLDelegate, OnExternalLoginFlowCompleteDelegate, bShouldContinueLoginFlow);

But, there are no delegates bound, so nothing happens…

Digging in to the source, it looks like FLoginFlowManager::AddLoginFlow needs to be called somewhere, as this is the only place that creates a “OnLoginFlowUIRequiredDelegate”…

Any hints? Anyone working with this yet?

This is only necessary for desktop platforms. iOS and Android have their own implementations with their respective SDKs.

Desktop needs to use an integrated web browser to deliver user interaction. Including the “LoginFlow” module in the game build.cs is necessary as I’m sure you’ve discovered.

For the desktop, there is only a small bit of code to add. It is all contained below. The delegate will fire and hand the game a slate widget. You can slot that widget inside native Slate code, or wrap it in a UNativeNativeWidgetHost and pass it into your blueprint code if you choose.

  // Initialize the login flow UI code
  UWorld* World = GetWorld();
  FName FacebookIdentifier = Online::GetUtils()->GetOnlineIdentifier(World, FACEBOOK_SUBSYSTEM);
  FName GoogleIdentifier = Online::GetUtils()->GetOnlineIdentifier(World, GOOGLE_SUBSYSTEM);
  ILoginFlowModule& LoginFlowModule = ILoginFlowModule::Get();
  LoginFlowManager = LoginFlowModule.CreateLoginFlowManager();
  if (!LoginFlowManager->AddLoginFlow(FacebookIdentifier, ILoginFlowManager::FOnDisplayPopup::CreateUObject(this, &ThisClass::OnDisplayLoginWidget)))
  {
            UE_LOG(LogWExp, Warning, TEXT("No Facebook subsystem configured. It will be unavailable"));
  }
  if (!LoginFlowManager->AddLoginFlow(GoogleIdentifier, ILoginFlowManager::FOnDisplayPopup::CreateUObject(this, &ThisClass::OnDisplayLoginWidget)))
  {
        	UE_LOG(LogWExp, Warning, TEXT("No Google subsystem configured. It will be unavailable"));
  }
    
  MyGameClass::FOnPopupDismissed MyGameClass::OnDisplayLoginWidget(const TSharedRef<SWidget>& DisplayWidget)
  {
        // create a login flow UI which contains the slate widget or native host widget blueprint implementable
            ...
       //return a FOnPopupDismissed delegate that the underlying system will call when the screen is closed for any reason.
  }
    
  void MyGameClass::OnDismissLoginWidget()
  {
        // Widget dismissed by login flow or possibly game related Blueprint code
        // For slate typically
        Overlay->RemoveSlot(LoginFlow.ToSharedRef());
  }
        
  FReply MyGameClass::CancelLoginFlow()
  {
      // Blueprint callable if outer UI has way to shutdown login flow
      if (LoginFlowManager.IsValid())
       {
        	LoginFlowManager->CancelLoginFlow();
        }
        return FReply::Handled();
   }

Thanks Josh. Where should this code be located?

Since it will be dealing with Slate/UMG/BP, somewhere related to your UI code. It doesn’t need to be anywhere specific.

Anywhere that is typically initialized once (AHUDMenu, APlayerControllerMenu, etc) and scoped only where login code is required.

Sorry to be vague, but there is no specific requirement, whatever works best for your use case.

Still having trouble here, can you go into a bit more detail? Is there any example code that is using this?

I added “LoginFlow” to PublicDependencyModuleNames, which results in this error:

Error Unable to determine module type for C:\uegh4.16.1\Engine\Plugins\Online\OnlineFramework\Source\LoginFlow\LoginFlow.Build.cs

I’m not quite sure what that is happening at the moment. If you moved that plugin/module under your MyGame/Plugins path that might temporarily fix this while I look into it further…

\MyGame\Plugins\Online\OnlineFramework\Source\LoginFlow\

Oh, first, did you add it to your .uproject file?

“Plugins”: [
{
“Name”: “OnlineFramework”,
“Enabled”: true
},

that might be more likely.

Same error, even after making the .uproject change.

Copying the LoginFlow folder into the game plugins folder did not resolve the issue.

Haven’t forgotten. Just busy internally. This code works in at least two of our internal projects. I’m engaging our support team to see if they can help repro this with a sample project.

The module is part of a plugin, so it is important that the .uplugin and .uproject setup are correct. Then including the module reference inside your top level game .build.cs file should be no big deal.

Other than debugging UnrealBuildTool.exe and putting a breakpoint inside the error that triggers, I’m not sure what the issue is at this point.

You can find the command line run in the build tool log files, or the NMake settings of Visual Studio.

It looks like LoginFlow isn’t properly defined in the OnlineFramework.uplugin file.

I’ve gone ahead and fixed that, and it should be a part of 4.17.

Try this:
Open up Engine\Plugins\Online\OnlineFramework\OnlineFramework.uplugin.

This is a JSON formatted filed.

Modify the Modules array to include an entry for LoginFlow:

"Modules": [
    {
        "Name": "Qos",
        "Type": "Runtime"
    },
    {
        "Name": "Party",
        "Type": "Runtime"
    },
    {
        "Name": "Lobby",
        "Type": "Runtime"
    },
    {
        "Name": "Hotfix",
        "Type": "Runtime"
    },
    {
        "Name": "Rejoin",
        "Type": "Runtime"
    },
    {
        "Name": "LoginFlow",
        "Type":  "Runtime"
    }
],

It looks like this module may not be completely up to date with our build rules, so you’ll also need to modify the module slightly.

Open up
Engine\Plugins\Online\OnlineFramework\Source\LoginFlow\LoginFlow.Build.cs and add the following near the top of the LoginFlow constructor:

PCHUsage = PCHUsageMode.UseSharedPCHs;

Thanks,
Jon N.

Thanks Jon…

I’ve fixed the LoginFlow module properly now that I understand what was going on. It will come down in a future release.

The PCHUsage is slightly different in my change to support this plugin being allowed under the game plugins directory also. Then the PrivatePCH.h file has been removed and relevant files adjusted.

Still unable to get this working. The provided code gives the error: error C2039: ‘GetUtils’: is not a member of ‘Online’

I suspect that there is an issue with the includes or header files.

Is there any example code I can look at?

Please help. This is a blocker for me.

Can you provide the full build error for this so I can see what file / location this is being thrown in.

Just searching, I’m not seeing anywhere OnlineFramework or LoginFlow should directly be using GetUtils, so it’s possible there’s something else weird going on here.

Thanks,
Jon N.

Thanks Jon! I really appreciate it.

Error (active) E0135 namespace “Online” has no member “GetUtils” Comp f:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 65

Error C2039 ‘GetUtils’: is not a member of ‘Online’ Comp F:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 65

Error C3861 ‘GetUtils’: identifier not found Comp F:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 65

To clarify, this is coming from the code that Josh posted above.

The code Josh posted above is sample code. I’m not sure if he created it, or pulled it out of a game, but he likely didn’t intend for you to directly copy and paste it.

Further, if it was grabbed from one of our games there’s always the possibility it wouldn’t work directly, as game’s may make modifications to engine code.

TL;DR you should have treated that as example or pseudo code to get an idea of how a flow looked.

The problem you’re running into is that your MyPlayerController.cpp class isn’t including the appropriate headers. These weren’t included in the sample code above, because again it was sample code.

Try adding the `#include “OnlineSubsystemUtils.h” to your MyPlayerController.cpp class.

I wouldn’t be surprised if there are other headers you’ll need to find / include, but that should get you passed the current issue.

Thanks,
Jon N.

Thanks Jon.

I’m sorry to be difficult, but all of this stuff was working in 4.15. I upgraded my engine, and now it’s all broken. I’m doing my best to try to stay positive and assist you guys as much as I can to identify the issues and get them fixed.

I understand that Josh’s code was meant as a sample. I understand that there are no examples, and no documentation - which makes this process difficult. I’m doing my best to make it work.

I will take the time to write up a blog post with working code, to illustrate how this is actually done - once I can get it working.

Including OnlineSubsystemUtils.h FIXED ‘GetUtils’: is not a member of ‘Online’. Awesome. Thank you.

Next issue is another include that I can’t figure out:

Error (active) E0020 identifier “ILoginFlowModule” is undefined Comp f:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 71

Error (active) E0020 identifier “LoginFlowManager” is undefined Comp f:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 72

I’ve tried including “LoginFlow”, “OnlineFramework”
I’ve tried putting them in the build.cs PublicDependencyModuleNames

Error Couldn’t find module rules file for module ‘OnlineFramework’. Comp F:\Unreal Projects\Comp\Intermediate\ProjectFiles\EXEC 1

Again, a working sample would be ideal, but we can go error by error until we get it working.

Error (active) E0020 identifier “ILoginFlowModule” is undefined Comp f:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 71

Add this #include "ILoginFlowModule.h"
Technically, that should solve the following one too, but it never hurts to be explicit.

Error (active) E0020 identifier “LoginFlowManager” is undefined Comp f:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 72

#include "ILoginFlowManager.h"

Just an FYI. All of the publicly available header files for LoginFlow can be found at Engine\Plugins\Online\OnlineFramework\Source\LoginFlow\Public.

If you run into anymore of these types of errors, you’ll just need to include the corresponding header file that has the given type defined.

For your own header files, I’d recommend using forward declarations.

Error Couldn’t find module rules file for module ‘OnlineFramework’. Comp F:\Unreal Projects\Comp\Intermediate\ProjectFiles\EXEC 1

OnlineFramework is not a module, it’s a plugin. It’s not going to have a module description.

Therefore, in your *.uplugin file you’ll need to set it is an enabled plugin (we covered this in one of the previous comments).

Do not attempt to include it in your Build.cs files.

LoginFlow is a module, not a plugin. It’s not going to have a plugin description.

Therefore, do not include it in your *.uplugin file.

Do put it in your Build.cs with the PublicDependencies.

Thanks,
Jon N.

Ok, after a lot of trial and error, I was able to get a bit further into the example code. Something I did also fixed the includes for ILoginFlowModule and ILoginFlowManager. Not exactly sure what it was.

I followed some other threads about how to get slate included. Which I think is required for FReply?

One line at a time, I suppose. Next up is this line:

if (!LoginFlowManager->AddLoginFlow(FacebookIdentifier, ILoginFlowManager::FOnDisplayPopup::CreateUObject(this, &AMyPlayerController::OnDisplayLoginWidget)))

Which errors out with:
Error (active) E0304 no instance of overloaded function “TBaseDelegate<WrappedRetValType, ParamTypes…>::CreateUObject [with WrappedRetValType=ILoginFlowManager::FOnPopupDismissed, ParamTypes=<const TSharedRef<SWidget, ESPMode::NotThreadSafe> &>]” matches the argument list Comp f:\Unreal Projects\Comp\Source\Comp\MyPlayerController.cpp 77

I created the OnDisplayLoginWidget like Josh’s example:

void AMyPlayerController::OnDisplayLoginWidget(const TSharedRef& DisplayWidget)