I have followed the docs for the firebase authentication and also a tutorial on this.
Assuming the token will be coming in the client from the header, I have created a custom authenticator class and I get an error for Task stating The type TaskQueuePb.TaskQueueQueryAndOwnTasksResponse.Task is not generic; it cannot be parameterized with arguments <FirebaseToken>
However, I don't see any other imports and the tutorial does not seem to be explaining more about it.
Please refer the code below:
package com.travelplannr.endpoint.firebase;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import com.google.api.server.spi.ServiceException;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Authenticator;
import com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueQueryAndOwnTasksResponse.Task;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseToken;
public class CustomAuthenticator implements Authenticator {
private static final Logger logger = Logger.getLogger(CustomAuthenticator.class.getName());
static {
try {
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
logger.log(Level.SEVERE, e.toString(), e);
}
}
@Override
public User authenticate(HttpServletRequest httpServletRequest) {
//get token
final String authorizationHeader = httpServletRequest.getHeader("Authorization");
//verify
if(authorizationHeader != null) {
Task<FirebaseToken> task = FirebaseAuth.getInstance().verifyIdToken(authorizationHeader.replace("Bearer ", ""));
//wait for the task
try {
Tasks.await(task);
} catch (ExecutionException e) {
} catch (InterruptedException e) {
}
FirebaseToken firebaseToken = task.getResult();
User user = new User(firebaseToken.getUid(), firebaseToken.getEmail());
return user;
}
return null;
}
}
Please help! Thanks in advance.
I think that there are two distinct problems here, in the same line of code. First, there seems to be a mismatch of the left-hand receiving type from the return type in your assignment. From what I can see from the FirebaseAuth Java API reference, the method signature is:
FirebaseToken verifyIdToken(String token)
So, verifyIdToken
returns a FirebaseToken
, but you're trying to assign it to a Task<FirebaseToken>
, which is a different, incompatible type. Secondly, Task<FirebaseToken>
is also an illegal type to try to use, because this Task
class isn't generic, so it can't be parameterized at all. This is the error that you're seeing from the compiler, but that detail becomes irrelevant if you drop the use of Task
altogether, because it's unnecessary:
FirebaseToken firebaseToken = FirebaseAuth.getInstance().verifyIdToken(authorizationHeader.replace("Bearer ", ""));
Just remove all of your other code around trying to use Task
and Tasks.await()
.
It seems like you might have been mixing and matching synchronous and asynchronous sources of information about how to make this call. Since the code you've written was going to immediately wait for the async task to be done anyway, you should probably just stick with the synchronous version of the API (verifyIdToken()
) instead of trying to use the asynchronous variant (verifyIdTokenAsync()
), which might have caused some confusion when trying to follow examples.