Refreshing Google Login Authentication Token with RxJava and Retrofit 2

This post will be about refreshing expired tokens from Google, which is a topic that the various blog posts on the internets and StackOverflow couldn’t seem to answer.

Android development is hilarious at times. It’s really just Java development, but motherfuck it’s stupidly difficult at times for no good reason at all, such as terrible documentation. I’m working on an app that uses Google Login as the primary authentication method. Just to clarify to the readers for what I’m talking about, it is referring to the Google Login documentation in this url

The above is the documentation for implementing Google Sign In in an Android app. The above documentation actually does a good job of showing you how to implement Google Sign In in an Android app. The problem is that the tokens you get back from Google expires on an hourly basis, meaning that you as a developer have to refresh the tokens once they expire. Unfortunately, the documentation for implementing this seems to be non-existent all over the internet. Just to give you an example, a screenshot of the StackOverflow post that gave me “I think I want to go back to web development” moment

My reaction when I read this ??????????????

Well, after a week of struggling, I finally solved this issue and I will be giving you straight up no-bullshit answer so that others don’t have to struggle like me.

Just as a preface, the app I’m working on is using Retrofit 2 and RxJava 2. A lot of blog posts and StackOverflow answers to this problem you’ll find online have solutions using RxJava 1.x. This is where the problem occurs. In RxJava 1.x, any non-successful HTTP “response” like 401, 400, 500 (basically anything else than 200, 201, 202, 204, you get the point), was considered to be an “error”. Thus, those responses were handled in the “onError” block and could be “retried” with the “retryWhen” method. To give you a quick example, here’s a code snippet on using RxJava 1 and Retrofit.

With RxJava 1.x, if the token had expired, you would have handled the response on the onError block and then you would refresh your token in the retryWhen section of your RxJava code.

In RxJava 2.x however, any normal HTTP responses are considered not to be errors, which if you think about it, is the correct way of handling it. Whether then HTTP response is 404, 500, or whatever, the server did what it was supposed to do, return a HTTP response. Thus, it technically isn’t an error. Therefore, to refresh the token in RxJava 2.x, you need to check for the proper http response in the onComplete block and then rerun your RxJava code if your token had expired. For example, in our app, the server returns a 401 response if the token from Google had expired. So without further ado, here’s the code

As you can see, in the onNext section of the code, I check if the response code is 401, and if it is 401, I refresh the token and call the method getBooksData() again recursively. This will retry the API call after the token has refreshed. And to show you the TokenRefresher class code

As you can see, all that I’m doing for is reimplementing silentLogin feature of the Google Login Android SDK. This seems to refresh the expired token into a valid one.

I hope this post helps people who are banging their head against the wall trying to figure out how to refresh Google Login tokens.