A little background:
I have a project in Android that will do basic authentication. I did the backend in SLIM PHP framework and it works. But I want to integrate Firebase in the project so I can store some images for the user, and basic chat feature.
So, I use the mAuth.signInWithCustomToken()
From what I understand a string token will be pass inside the function. I use firebase/php-jwt
for the php part and added some lines on the backend. On the projectname/public/index.php
I added this function:
function create_custom_token($uid) {
$service_account_email = "service account email here";
$private_key = "privatekey here";
$now_seconds = time();
$payload = array(
"iss" => $service_account_email,
"sub" => $service_account_email,
"aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat" => $now_seconds,
"exp" => $now_seconds+(60*60), // Maximum expiration time is one hour
"uid" => $uid
);
return JWT::encode($payload, $private_key, "HS256");
}
And to call that function I put the code below inside the login router:
if($result == USER_AUTHENTICATED){
$user = $db->getUserByUsername($username);
$response_data = array();
$response_data['error']=false;
$response_data['message'] = 'Login Successful';
$response_data['user']=$user;
$jwt = create_custom_token($username);
$response_data['token']=$jwt;
$response->write(json_encode($response_data));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
}
So basically, I use the username
as uid
which makes since it is unique.
And on the android, In the LoginActivity.java
@Override
public void onValidationSucceeded() {
String username = editTextUsername.getText().toString();
String password = editTextPassword.getText().toString();
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Logging in...");
dialog.show();
dialog.setCancelable(false);
Call<LoginResponse> call = RetrofitClient
.getInstance().getApi().userLogin(username, password);
call.enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
LoginResponse loginResponse = response.body();
if (!loginResponse.isError()) {
mAuth.signInWithCustomToken(loginResponse.getToken())
.addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
SharedPrefManager.getInstance(LoginActivity.this)
.saveUser(loginResponse.getUser());
dialog.dismiss();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
// If sign in fails, display a message to the user.
dialog.dismiss();
Toast.makeText(LoginActivity.this, loginResponse.getToken(),
Toast.LENGTH_SHORT).show();
}
}
});
} else {
dialog.dismiss();
Toast.makeText(LoginActivity.this, response.body().getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
Toast.makeText(LoginActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
dialog.dismiss();
}
});
}
This is the LoginResponse
Model
public class LoginResponse {
private boolean error;
private String message;
private User user;
private String token;
public LoginResponse(boolean error, String message, User user, String token) {
this.error = error;
this.message = message;
this.user = user;
this.token = token;
}
public boolean isError() {
return error;
}
public String getMessage() {
return message;
}
public User getUser() {
return user;
}
public String getToken() {
return token;
}
}
Using Postman to test the API, This is the result from POSTMAN So you can say, that it is working fine.
On Android however, When I try to login, by giving the same correct username and password,it throws an error `
The Custom token format is invalid. Please check the documentation. [SIGNATURE_INVALID]
Just in case you want to know, this the token from the result eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmaXJlYmFzZS1hZG1pbnNkay1tY3l4MEBmbGl0dGVyLWMxNzU2LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic3ViIjoiZmlyZWJhc2UtYWRtaW5zZGstbWN5eDBAZmxpdHRlci1jMTc1Ni5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsImF1ZCI6Imh0dHBzOlwvXC9pZGVudGl0eXRvb2xraXQuZ29vZ2xlYXBpcy5jb21cL2dvb2dsZS5pZGVudGl0eS5pZGVudGl0eXRvb2xraXQudjEuSWRlbnRpdHlUb29sa2l0IiwiaWF0IjoxNTM0MzQ4ODI5LCJleHAiOjE1MzQzNTI0MjksInVpZCI6Imp1c3Rpbi5sdWNhcyJ9.cQwNFWshi_0nMiZKpjXajJ4MnB9E7kGPlFB-kWZPmfo
Any idea guys? Maybe I have to do something on the client side?
To anyone who might see this one. The answer is: make sure to set your PC/Desktop/Laptop to the correct time/timezone. Got the answer the next day after posting the question.