Primico Primico - 17 days ago 8
Android Question

Return a value from overridden callback

I am making a call to get a FireBase token, then using that token to get a token from my server.

I want

userSignIn()
to return the token from my server.

Does anyone know how can I return the token to
userSignIn()
?

@Override
public String userSignIn(String email, String password, String authType) throws Exception {
login(email, password, authType, new OnLoginResponseCallback() {
@Override
public String onLoginResponse(boolean success, String token) {
**return token;** // how do I return this to userSignIn???
}
});
}

public interface OnLoginResponseCallback {
public String onLoginResponse(boolean success, String token);
}

public void login(String email, String password, String authType, final OnLoginResponseCallback callback) throws Exception {
getFirebaseToken(email, password, new OnFirebaseTokenResponseCallback() {
@Override
public String onFirebaseTokenResponse(boolean success, String token) {
getAuthToken(token, null, new OnAuthTokenResponseCallback(){
@Override
public String onAuthTokenResponse(boolean success, JSONObject response){
try {
String access_token = response.getString("access_token");
callback.onLoginResponse(true, access_token);
}
catch (JSONException ex) {

}
}
});
}
});
}

public interface OnFirebaseTokenResponseCallback {
public String onFirebaseTokenResponse(boolean success, String token);
}

public void getFirebaseToken(String email, String password, final OnFirebaseTokenResponseCallback callback) {
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {

} else {
AuthResult result = task.getResult();
FirebaseUser user = result.getUser();
user.getToken(false).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
@Override
public void onComplete(@NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
try {
String token = task.getResult().getToken();
callback.onFirebaseTokenResponse(true, token);
}
catch (Exception ex) {

}
} else {

}
}
});
}
}
});
}


public interface OnAuthTokenResponseCallback {
public String onAuthTokenResponse(boolean success, JSONObject response);
}

public void getAuthToken(String token, String refreshToken, final OnAuthTokenResponseCallback callback) throws JSONException {
RequestParams params = new RequestParams();
if (refreshToken != null)
{
params.add("grant_type", "refresh_token");
params.add("refresh_token", refreshToken);
}
else if (token != null)
{
params.add("grant_type", "urn:ietf:params:oauth:grant-type:firebase_token");
params.add("assertion", token);
}
else if (refreshToken == null && token == null)
{
params.add("grant_type", "password");
params.add("username", "");
params.add("password", "");
}
AuthClient.post("connect/token", params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, JSONObject response) {
try {
callback.onAuthTokenResponse(true, response);
} catch (Exception ex) {

}
}
@Override
public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, Throwable throwable, JSONObject response) {
callback.onAuthTokenResponse(false, new JSONObject());
}
});
}


UPDATE:

Thanks. I removed the redundant method, and call login like this:

.login(userName, userPass, mAuthTokenType, new OnLoginResponseCallback() {
@Override
public void onLoginResponse(boolean success, String token) {
data.putString(AccountManager.KEY_ACCOUNT_NAME, userName);
data.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
data.putString(AccountManager.KEY_AUTHTOKEN, token);
data.putString(PARAM_USER_PASS, userPass);
}
});


I think it works but haven't had a chance to fully test it yet. One thing I am not certain about is I am trying to modify "data" with a value from "token", yet "data" is a Bundle that is final, so I am not sure if that works or not. Will test later. Thanks.

Answer

You called a method that basically calls another method of the same signature

@Override
public String userSignIn(String email, String password, String authType) throws Exception {
    login(email, password, authType, new OnLoginResponseCallback() {
        @Override

Instead, wherever you would call userSignIn, you call login, and pass in that anonymous class. You can't return from these inner methods, because that isn't how callbacks work. You use the parameters of the interface methods to "continue" your logic. Like, do login, callback to the main function with some user info, use this info to make a new request, have a callback waiting for that data, that passes back data to some other method. It's all void methods calling other methods. No return statements

Although, in Javascript, you can read this

How to return value from an asynchronous callback function?