Diagnosing Unknown Google Account Linking Errors
In this post I wanted to address a path forward after getting either no errors, or undocumented errors, in your Google Cloud Console logs during account linking. This topic came about during a project I was working on with David Whitters, an Embedded Software Engineer at Bissell. David Whitters and I share a great dynamic where his expertise is in the embedded and IoT side, and mine is with the cloud and frontend. Account linking is a special flow for if you need to interact with an IoT device using Google Assistant and a custom backend. There are other use-cases for account linking, and you can read more about this via Google’s documentation, but this was our focus today.
There are many pieces to this puzzle, and a lot of tech is interchangeable. However, in this example, we were using Firestore as the backend service, and Auth0 as the authentication service. These are great tools that take care of many otherwise undocumented areas of account linking. Once all of this is in place, you’re troubleshooting the account linking inside the Google Assistant app, and you’ve started getting unknown errors, we’re ready to begin.
You should have an Auth0 endpoint setup with a login and token url provided to the Google Actions dashboard for account linking. Your Auth0 endpoint should also have at a minimum these grant types:
When you use the Google Assistant app to “account link” to your service, Google will go to your authorization url to perform an OAuth login. They will also use the token url for the token exchange to interact with the either Home Graph api, or something else you need.
We’re also assuming that you have a fulfillment endpoint for Google Assistant to hit after a successful login and token exchange. This is setup in the Actions tab, and in our example, exists on our Firestore service.
When you run through your account linking steps, you open the Google Assistant app and go to Profile -> Devices -> Add Devices -> Link a Smart Home Device -> The name of your project. This brings up your authentication endpoint, and after logging in, should succeed and say something like “<Project Name> has successfully linked.” And this is great! However, that only tells us that the authentication succeeded, nothing else. Below are the two steps going on with account linking:
Google authenticates with our service
Google hits our fulfillment url with the new token
We’re concerned with if you get an error immediately after the success message like below, denoting that step #2 failed:
This error is meaningless on its own. Where can the real error be found? If you follow all the guides out there about using Firestore with Google Assistant, your error is probably nowhere. If you’re lucky, you may get a seemingly meaningless error in the Google Console logs like this:
All it says is “syncLog” and really nothing else. In some cases, it may even say “BACKEND_FAILURE_URL_ERROR.”
What can we do? Logically, the next step in Google’s flow is to call on our fulfillment endpoint. So the error must be there, right? In my case, the fulfillment endpoint wasn’t even getting called to begin with. It never got to that step. However, we’re on the right track. Because Firestore is a Google service, what we need to do, that no docs ever mention in regards to account linking, is link cloud logging. Before I knew about this, I was stuck going down various paths, convinced that something bigger was wrong, when it was actually quite simple. This is when it’s great to have a second person looking into errors with you, because David Whitters was thankfully able to find this feature while I was looking in totally different places.
In your Firestore project website, go to Project Settings -> Integrations -> Cloud Logging -> Link. After this, finally we get to see what that error is talking about in the Google Assistant app!
Now, keep in mind that this error is from my Firestore endpoint, so the traces and payload messages are customized for my own api. So now I know that there’s actually a jwt issue when the account linking login initially succeeds, but then tries to query my user’s Home Graph api via the fulfillment endpoint. Your error will most likely be different, but will also give you some newfound clarity about what’s going wrong.
Just in case you’re following along and are now stuck on the malformed jwt error, I wanted to include the solution for that as well. Know that you need to use the right algorithm (RS256), and provide a default audience so that Google will receive a full jwt instead of an opaque jwt. You can do this by going to:
Auth0 settings -> Tenant Settings -> API Authorization Settings -> Default Audience.
You can find which audience to use by going to:
Applications -> Your application -> APIs -> API Identifier.
I hope that this is helpful to anyone trying to troubleshoot account linking issues, and removes just one more blocker for a complex, highly undocumented area of Google services. And I want to give a special thanks to David Whitters for contributing to this project and helping me work through connecting the dots between IoT Core, Firestore, and Google Cloud Logging.
You can find David Whitters on LinkedIn here: https://www.linkedin.com/in/david-whitters-784076a9/
Want to talk more about Google services, IoT, and account linking? I’d love to chat with you! You can meet me in the official Bravo LT Discord Server!
Written by David Crawford, Mobile App Developer