Signin With Apple

Backendless Version (3.x / 5.x, Online / Managed / Pro )

6.0.10, Online

Client SDK (REST / Android / Objective-C / Swift / JS )

JS

Application ID

028AF23A-DE67-970F-FF7B-CE73726F3E00.

I followed the Signin With Apple post found at https://backendless.com/feature/sign-in-with-apple/, and at the end it says

The result of the AppleAuth API service login method is a registered BackendlessUser object that should be set manually in your code as the current user in your application.

I cannot find a setCurrentUser function under UserService, and we rely on functions like isValidLogin and getCurrentUser heavily in our app flow
(i.e. we have Enable Multiple Logins disabled to prevent users from using the app on multiple devices (to prevent multiple users to use the same credentials similar to a Netflix scenario).
And we update the UI (i.e. pop up the login form and prevent other use) based on isValidLogin.
And for most of our db records, the current user (which we retrieve by calling getCurrentUser) is used to identify the user creating the record).

What alternative can be used to replace such functionality when a user is not technically logged in to Backendless if Signin With Apple was used.

Please advise.

Thank you.

Hello, @karim-wazzan

If I understood you correctly, simply login a user from the result of AppleAuth API service’s login method passing its objectId prop as the only argument to
Backendless.UserService.login( objectId )

Regards, Igor

1 Like

@Igor_Bogunkov, this is actually EXACTLY what i want, thank you very much!

Hello @Igor_Bogunkov

So there are few issues with Backendless.UserService.login( objectId ):

  1. The method overload with the 1 argument (objectId) is not defined in the typescript definitions found in the NPM Backendless package ( backendless.d.ts ), so to call the function i had to do it like this:
    (Backendless.UserService as any).login( objectId )

  2. Given that my app runs client side, i am using the JS API Key, and the method returns an error 400:
    {"code":2014,"message":"Login by object id is allowed only for Code Runner API key","errorData":{}}

  3. I tried using the Code Runner API Key just when calling the method,

  • Backendless.initApp(APP_ID, CodeRunner_API_KEY);
  • Backendless.UserService.login( objectId )
  • Backendless.initApp(APP_ID, JS_API_KEY);
  • Backendless.UserService.isValidLogin() always returns false.

I assume this is because the login method was called with a different API Key.

Please advise.

Thanks!

Hi, @karim-wazzan

About your comments:

  1. We have created the internal ticket - BKNDLSS-22601 for this point. It will be added to our JS SDK.

  2. In fact, the login using the objectId is only available with the Code Runner API Key. However, we do not recommend using this key when creating applications for security reasons.

  3. We can offer you a solution where you do not need to use several api keys:

  • Make logout

  • Use LoginWithApple in order to get User`s objectId and token-value

  • Set it to the localstorage

      Backendless.LocalCache.set(Backendless.LocalCache.Keys.STAY_LOGGED_IN, true)
      Backendless.LocalCache.set(Backendless.LocalCache.Keys.USER_TOKEN, 'THE_USER_TOKEN')
      Backendless.LocalCache.set(Backendless.LocalCache.Keys.CURRENT_USER_ID, 'THE_USER_OBJECT_ID')
    
  • Check it via Backendless.UserService.isValidLogin()

Regards,
Marina

1 Like

Hello @Marina.Kan,

Thank you for your quick reply.

Important note, does this method
const loggedInUser = await Backendless.CustomServices.invoke('AppleAuth', 'login', 'TOKEN VALUE')
return a User Object with user-token like the Backendless.UserService.login() method??

If yes, then the following flow should result basically give the same result as calling Backendless.UserService.login() :

  • LoginWithApple() returns User
  • Backendless.LocalCache.set(Backendless.LocalCache.Keys.STAY_LOGGED_IN, true)
  • Backendless.LocalCache.set(Backendless.LocalCache.Keys.USER_TOKEN, User.user-token)
  • Backendless.LocalCache.set(Backendless.LocalCache.Keys.CURRENT_USER_ID, User.objectId)
  • Backendless.UserService.isValidLogin() should now return true
  • Backendless.UserService.getCurrentUser() should now return User same as LoginWithApple() returns User but without ‘user-token’
  • Calling Backendless.UserService.logout() should clear the cache, and calling Backendless.UserService.isValidLogin() should now return false

Please advise.

Thanks!

@karim-wazzan, using this method

const loggedInUser = await Backendless.CustomServices.invoke('AppleAuth', 'login', 'TOKEN VALUE')

you get a token. But after that you need to set it to SDK.
We reccomend you to use the solution described above to solve your issue.

Regards,
Marina

When you say

You mean like this?

and can i please know, if we call

Backendless.UserService.logout()

Can the user sign in again by repeating the same steps?
i.e. call const loggedInUser = await Backendless.CustomServices.invoke('AppleAuth', 'login', 'TOKEN VALUE'), then Backendless.LocalCache.set ?

Hello @karim-wazzan

We just released our JS-SDK with a new method to set up current user:

Backendless.UserService.setCurrentUser(userObject, stayLoggedIn)

so now, you can follow by the following steps

  1. login with apple using the API Service Backendless.CustomServices.invoke('AppleAuth'...
  2. then setup the returned user to the JS-SDK by using the setCurrentUser
  3. then you can check if this user is logged in isValidLogin
  4. and finally if you need to do logout just call logout method
const loggedInUser = await Backendless.CustomServices.invoke('AppleAuth', 'login', 'TOKEN VALUE')

Backendless.UserService.setCurrentUser( loggedInUser, true )

await Backendless.UserService.isValidLogin() // it should return true

... do what you need

await Backendless.UserService.logout() // use this method for regular logout

Regards, Vlad

1 Like

Amazing @vladimir-upirov, this is all I need, thank you and @Marina.Kan and @Igor_Bogunkov for your help and support!