Hi,
I am not able to find any documents related integrating apple sign in for flutter app with backendless service. Can anyone advise?
Hi,
I am not able to find any documents related integrating apple sign in for flutter app with backendless service. Can anyone advise?
Hello, @CHEONG_YEW_HOONG.
Are you using backendless-sdk for flutter, or ui builder packaged in native shell with flutter?
Best Regards, Nikita.
You need to integrate “Login with Apple” service from Marketplace into your app.
Follow “Installation Instructions” here.
Then you need to add sign_in_with_apple: ^3.3.0 dependency into your pubspec.yaml file.
And with this code you can login via apple:
final credential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions(
clientId: 'paste your clientId here',
redirectUri: Uri(),
));
result = await Backendless.customService.invoke('AppleAuth',
'login', credential.identityToken); //get your user
result = BackendlessUser.fromJson(result);
Do not forget to add apple sign-in into xcode project.
Best Regards, Nikita.
Hi @Nikita_Fedorishchev ,
I am facing an issue that the InitApp not able to check the logged in user that using apple login method. Thus, i have failed to stay log in the user. However, this InitApp works with username/password login method.
Anyway, i am able to register the user using apple sign in method and i can see the user created in backendless user database.
class InitApp {
static final String apiKeyAndroid = 'XXXXXXXX';
static final String apiKeyiOS = 'XXXXXXXX';
static final String appID = 'XXXXXXXX';
static void initializeApp(BuildContext context) async {
await Backendless.initApp(
applicationId: appID,
iosApiKey: apiKeyiOS,
androidApiKey: apiKeyAndroid);
String result = await context.read<UserService>().checkIfUserLoggedIn();
if (result == 'OK') {
Navigator.pushNamedAndRemoveUntil(
context, '/splash1Page', (route) => false);
} else {
//Navigator.popAndPushNamed(context, RouteManager.loginPage);
Navigator.pushNamedAndRemoveUntil(context, '/', (route) => false);
}
}
}
Future<String> checkIfUserLoggedIn() async {
String result = 'OK';
bool? validLogin = await Backendless.userService
.isValidLogin()
.onError((error, stackTrace) {
result = error.toString();
});
if (validLogin != null && validLogin) {
String? currentUserObjectId = await Backendless.userService
.loggedInUser()
.onError((error, stackTrace) {
result = error.toString();
});
if (currentUserObjectId != null) {
Map<dynamic, dynamic>? mapOfCurrentUser = await Backendless.data
.of("Users")
.findById(currentUserObjectId)
.onError((error, stackTrace) {
result = error.toString();
});
if (mapOfCurrentUser != null) {
_currentUser = BackendlessUser.fromJson(mapOfCurrentUser);
globals.userId = _currentUser?.getUserId();
globals.userEmail = _currentUser?.email;
print(globals.userId.toString() + globals.userEmail.toString());
notifyListeners();
} else {
removeTokenAndData();
result = 'NOT OK';
}
} else {
removeTokenAndData();
result = 'NOT OK';
}
} else {
removeTokenAndData();
result = 'NOT OK';
}
return result;
}
Can i have your advise please?
Hello, @CHEONG_YEW_HOONG.
Try to use the setCurrentUser method after Apple login.
Best Regards, Nikita
Hi @Nikita_Fedorishchev ,
Unfortunately, setCurrentUser didn’t work either.
var appleAuth = await Backendless.customService
.invoke('AppleAuth', 'login', appleIdCredential.identityToken);
appleAuth = BackendlessUser.fromJson(appleAuth);
print(appleAuth);
**Backendless.userService.setCurrentUser(appleAuth);**
I found a problem with the setCurrentUser method. I’ll let you know when it’s fixed.
Best Regards, Nikita.
Problem was fixed. You need to use last version of backendless_sdk
(7.2.6).
This code works:
var result;
final credential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions(
clientId: 'your clientId',
redirectUri: Uri(),
));
result = await Backendless.customService.invoke('AppleAuth',
'login', credential.identityToken); //get your user
result = BackendlessUser.fromJson(result);
await Backendless.userService
.setCurrentUser(result, stayLoggedIn: true);
Best Regards, Nikita.
Hi @Nikita_Fedorishchev ,
Thanks for updating the sdk(7.2.6). However, the outcome is the same. InitApp not able to detect logged in user(if using apple sign in) and navigated to login page…
apple login function:
Future<void> appleSignIn(BuildContext context) async {
try {
final appleIdCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
);
if (appleIdCredential != null) {
var appleAuth = await Backendless.customService
.invoke('AppleAuth', 'login', appleIdCredential.identityToken);
appleAuth = BackendlessUser.fromJson(appleAuth);
await Backendless.userService
.setCurrentUser(appleAuth, stayLoggedIn: true);
Navigator.of(context).popAndPushNamed(RouteManager.splash2Page);
} else {
const snackBar = SnackBar(content: Text("Not able to sign in"));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
} catch (e) {
final snackBar = SnackBar(content: Text(e.toString()));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
InitApp function:
class InitApp {
static const String apiKeyAndroid = 'XXXXXXXX';
static const String apiKeyiOS = 'XXXXXXXX';
static const String appID = 'XXXXXXXX';
static void initializeApp(BuildContext context) async {
await Backendless.initApp(
applicationId: appID,
iosApiKey: apiKeyiOS,
androidApiKey: apiKeyAndroid);
String result = await context.read<UserService>().checkIfUserLoggedIn();
if (result == 'OK') {
Navigator.pushNamedAndRemoveUntil(
context, '/splash1Page', (route) => false);
} else {
Navigator.pushNamedAndRemoveUntil(context, '/', (route) => false);
}
}
}
check user logged in function:
Future<String> checkIfUserLoggedIn() async {
String result = 'OK';
bool? validLogin = await Backendless.userService
.isValidLogin()
.onError((error, stackTrace) {
result = error.toString();
});
if (validLogin != null && validLogin) {
String? currentUserObjectId = await Backendless.userService
.loggedInUser()
.onError((error, stackTrace) {
result = error.toString();
});
if (currentUserObjectId != null) {
Map<dynamic, dynamic>? mapOfCurrentUser = await Backendless.data
.of("Users")
.findById(currentUserObjectId)
.onError((error, stackTrace) {
result = error.toString();
});
if (mapOfCurrentUser != null) {
_currentUser = BackendlessUser.fromJson(mapOfCurrentUser);
notifyListeners();
} else {
removeTokenAndData();
result = 'NOT OK';
}
} else {
removeTokenAndData();
result = 'NOT OK';
}
} else {
removeTokenAndData();
result = 'NOT OK';
}
return result;
}
The bool? validLogin always return as false after reopen the app while logged in using apple sign in.
With a default login, everything works as it should?
I have already reproduced the problem, we are working on a solution(isValidLogin seems broken after using setCurrentUser).
We have an internal ticket on this issue - BKNDLSS-30041. Our developer will take a look at it more closely. Stay tuned, we will reply to you in this thread when have more information about the problem.
Regards,
Marina
Resolved in new version of Flutter-sdk(8.0.0).