Skip to content

Instantly share code, notes, and snippets.

@janakagamini
Last active June 4, 2021 06:36
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save janakagamini/74c3b403edac31a92ad1d589d0a01c9d to your computer and use it in GitHub Desktop.
Save janakagamini/74c3b403edac31a92ad1d589d0a01c9d to your computer and use it in GitHub Desktop.
A simple Interceptor to include a Firebase user's id token in all requests. Useful for authenticating Firebase users with a custom backend. See: https://firebase.google.com/docs/auth/admin/verify-id-tokens#retrieve_id_tokens_on_clients)
public class FirebaseUserIdTokenInterceptor implements Interceptor {
// Custom header for passing ID token in request.
private static final String X_FIREBASE_ID_TOKEN = "YOUR-CUSTOM-HEADER";
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
try {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null) {
throw new Exception("User is not logged in.");
} else {
Task<GetTokenResult> task = user.getToken(true);
GetTokenResult tokenResult = Tasks.await(task);
String idToken = tokenResult.getToken();
if (idToken == null) {
throw new Exception("idToken is null");
} else {
Request modifiedRequest = request.newBuilder()
.addHeader(X_FIREBASE_ID_TOKEN, idToken)
.build();
return chain.proceed(modifiedRequest);
}
}
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
}
@janakagamini
Copy link
Author

// Use it like
OkHttpClient okHttpClient = new OkHttpClient.Builder()
  .addInterceptor(new FirebaseUserIdTokenInterceptor())
  .build();

Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("Your API url")
  .client(okHttpClient)
  .build();

@levon93
Copy link

levon93 commented Aug 5, 2018

Could you please modify your code, because getToken() is deprecated.

@johncpang
Copy link

Just replace getToken(...) with getIdToken(...)

Task<GetTokenResult> task = user.getIdToken(true);

@apexkid
Copy link

apexkid commented Aug 16, 2018

Thanks. This was great.

@GianhTran
Copy link

work like a charm, thank

@georgeRCluj
Copy link

Great solution, thank you! ;)

@gowthamgts
Copy link

gowthamgts commented Apr 26, 2020

getIdToken parameter should be false, else this will force fetch token again even if they are not expired.

@ashishtaldeokar
Copy link

Agreed! as mentioned by @gowthamgts
For generic usage keep parameter as false because,

fireBaseUser!!.getIdToken(true)
will always fetch a new token (adds time as it needs a n/w call)

fireBaseUser!!.getIdToken(false)
will only fetch a new token if the old one is expired (saves time as it fetches cached token)

if the token is expired it will automatically fetch a new one for you.

here's an example for kotlin fam

fun getJwtToken(): String {
    val result = Tasks.await(fireBaseUser!!.getIdToken(false))
    return result!!.token!!
}

@tangxiaocheng
Copy link

Interesting. I've been tried on this method for hours. It didn't fix my problem. I was so confused.

After checkoutfirebase auth

Finally, I went through.

class AuthInterceptor : Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): okhttp3.Response { return try { val user = FirebaseAuth.getInstance().currentUser if (user == null) { throw Exception("User is not logged in.") } else { val task: Task<GetTokenResult> = user.getIdToken(false) val tokenResult = Tasks.await(task) val idToken = tokenResult.token if (idToken == null) { throw Exception("idToken is null") } else { val original = chain.request() val originalHttpUrl = original.url val url = originalHttpUrl.newBuilder() .addQueryParameter("auth", "$idToken") .build() val requestBuilder = original.newBuilder() .url(url) val request = requestBuilder.build() chain.proceed(request) } } } catch (e: Exception) { throw IOException(e.message) } } }

Adding addQueryParameter worked for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment