Hi @Salman_lartey ,
As @Desislava_St_Stefanova mentioned, the custom user data is stored in the JWT, so it can be stale if you update the custom user data after logging in and before the next refresh of the access token. Note this section of the docs:
App Services does not dynamically update the value of the User.customData
immediately when underlying data changes
How are you creating the custom user data documents? If it’s after login, consider adding a call to user.refreshCustomData()
before trying to access it.
Hi @Kiro_Morkos ,
I do it as follows,
Future<userModel.User> logInWithGoogle() async {
final result = await login();
final ggAuth = await result!.authentication;
final credentials = Credentials.jwt(ggAuth.idToken!);
final user = await _app.logIn(credentials);
await user.refreshCustomData(); // Refresh the custom data
final AuthLink authLink = AuthLink(
getToken: () async {
return 'Bearer ${ggAuth.idToken!}';
},
);
final Link link = authLink.concat(ApiConstants.httpLink);
final GraphQLClient client = GraphQLClient(
link: link,
cache: GraphQLCache(),
);
final MutationOptions options = MutationOptions(
document: gql('''
mutation Login(\$displayName: String!, \$email: String!, \$photoUrl: String!, \$userId: String!, \$isActive: Boolean!) {
login(displayName: \$displayName, email: \$email, photoUrl: \$photoUrl, userId: \$userId, isActive: \$isActive) {
userId
email
displayName
photoUrl
isActive
}
}
'''),
variables: <String, dynamic>{
'displayName': user.profile.name ?? 'Unknown',
'email': user.profile.email!,
'photoUrl': user.profile.pictureUrl!,
'userId': user.id,
'isActive': true
},
);
final QueryResult result2 = await client.mutate(options);
if (result2.hasException) {
throw Exception('Error logging in: ${result2.exception}');
}
final data = result2.data!['login'];
user2 = userModel.User.fromJson(data);
// Save the user's authentication credentials in the device's secure storage
final storage = FlutterSecureStorage();
await storage.write(key: 'jwtToken', value: ggAuth.idToken!);
// await storage.write(key: 'lives', value: user2.lives);
_token = _app.currentUser!.accessToken;
// _token = ggAuth.idToken!;
// _exprireDate = DateTime.now().add(Duration: (seconds))!;
final customUserData = user.customData; // Access the custom data
user.refreshCustomData();
logger.d(customUserData);
notifyListeners();
return user2;
}
And even when i add it in i still get Null:
@override
void initState() {
super.initState();
final realmService = Provider.of<RealmService>(context, listen: false);
final user = realmService.currentUser;
user!.refreshCustomData();
socketClient.emit('setUser', user.profile.email);
try {
setState(() {
final customUserData = user.customData;
customUserData!.refreshCustomData();
logger.d(customUserData);
});
} catch (e) {}
Can you await
each call to refreshCustomData
to ensure the future is resolved before try to access the custom user data?
@Kiro_Morkos ,I have set it as follow:
Future<userModel.User> logInWithGoogle() async {
final result = await login();
final ggAuth = await result!.authentication;
final credentials = Credentials.jwt(ggAuth.idToken!);
final user = await _app.logIn(credentials);
await user.refreshCustomData(); // Refresh the custom data
final AuthLink authLink = AuthLink(
getToken: () async {
return 'Bearer ${ggAuth.idToken!}';
},
);
final Link link = authLink.concat(ApiConstants.httpLink);
final GraphQLClient client = GraphQLClient(
link: link,
cache: GraphQLCache(),
);
final MutationOptions options = MutationOptions(
document: gql('''
mutation Login(\$displayName: String!, \$email: String!, \$photoUrl: String!, \$userId: String!, \$isActive: Boolean!) {
login(displayName: \$displayName, email: \$email, photoUrl: \$photoUrl, userId: \$userId, isActive: \$isActive) {
userId
email
displayName
photoUrl
isActive
}
}
'''),
variables: <String, dynamic>{
'displayName': user.profile.name ?? 'Unknown',
'email': user.profile.email!,
'photoUrl': user.profile.pictureUrl!,
'userId': user.id,
'isActive': true
},
);
final QueryResult result2 = await client.mutate(options);
if (result2.hasException) {
throw Exception('Error logging in: ${result2.exception}');
}
final data = result2.data!['login'];
user2 = userModel.User.fromJson(data);
final storage = FlutterSecureStorage();
await storage.write(key: 'jwtToken', value: ggAuth.idToken!);
_token = _app.currentUser!.accessToken;
final customUserData = user.customData; // Access the custom data
await user.refreshCustomData(); // Refresh the custom data
logger.d(customUserData);
notifyListeners();
return user2;
}
And it is still showing null, idk what im doing wrong:
Okay, I managed to fix it by doing the following code:
Future<userModel.User> logInWithGoogle() async {
final result = await login();
final ggAuth = await result!.authentication;
final credentials = Credentials.jwt(ggAuth.idToken!);
final user = await _app.logIn(credentials);
currentUser = user;
final AuthLink authLink = AuthLink(
getToken: () async {
return 'Bearer ${ggAuth.idToken!}';
},
);
final Link link = authLink.concat(ApiConstants.httpLink);
final GraphQLClient client = GraphQLClient(
link: link,
cache: GraphQLCache(),
);
final MutationOptions options = MutationOptions(
document: gql('''
mutation Login(\$displayName: String!, \$email: String!, \$photoUrl: String!, \$userId: String!, \$isActive: Boolean!) {
login(displayName: \$displayName, email: \$email, photoUrl: \$photoUrl, userId: \$userId, isActive: \$isActive) {
userId
email
displayName
photoUrl
isActive
}
}
'''),
variables: <String, dynamic>{
'displayName': user.profile.name ?? 'Unknown',
'email': user.profile.email!,
'photoUrl': user.profile.pictureUrl!,
'userId': user.id,
'isActive': true
},
);
final QueryResult result2 = await client.mutate(options);
if (result2.hasException) {
throw Exception('Error logging in: ${result2.exception}');
}
await currentUser!.refreshCustomData(); // Refresh the custom data
logger.d(currentUser!.customData);
final data = result2.data!['login'];
user2 = userModel.User.fromJson(data);
final storage = FlutterSecureStorage();
await storage.write(key: 'jwtToken', value: ggAuth.idToken!);
_token = _app.currentUser!.accessToken;
final customUserData = user.customData; // Access the custom data
await currentUser!.refreshCustomData(); // Refresh the custom data
logger.d(customUserData);
notifyListeners();
return user2;
}
system
(system)
Closed
May 24, 2023, 9:24pm
27
This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.