Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting Google User ID in Node.js in Firebase Functions for Assistant App

Tags:

I'm getting started with Google Cloud Platform.

I'm developing an Android App that will collect information and store it in a Firebase App. The idea is that a Google Assistant function can query this information and read it back- eg

OK Google, Talk To Simons App, Tell me the last time XYZ was done

The problem I've got however, is to get this being multi user.

I've got the Android App collecting data and putting it into the cloud. I'm using the FirebaseUser and using getUid() in the Android app to get a unique id which is a 28 character string like uVHkia8RRgWD8GGPVvW4AUDUK2.

I've setup Actions on Google, got it hooked into API.AI with Web Fulfilment and got Node.js working in firebase functions.

Unfortunately, the UserID I get back looks more like:HTge48H0CF2FC5jJQCigFBc-UCQ

The problem is that this UserID is not the same as the UserUID I got from Filebase User.

Im using

let ApiAiApp = require('actions-on-google').ApiAiApp;
const app = new ApiAiApp({request: request, response: response});

and

const userId = app.getUser().userId;

What am I missing? I see references to OAuth2, Account Linking etc. I'm not entirely sure what to do at this point. All I need to do at the moment, is get the User UID like I get from FirebaseUser.getUID() in order to look the data up in the Firebase Database.

I think the rest should be straight forward.

There's loads of documentation on linking to Firebase from the Assistant, but very little on actually authenticating. So far I've not setup an flows, like Authorization Code Flows, Implicit Flows, or set a username/password against API.AI and the Fulfilment option. Quite frankly Im not sure what needs to go where at this point.

like image 541
Simon Avatar asked Sep 01 '17 18:09

Simon


1 Answers

The user provided by app.getUser().userId is designed as a persistent anonymous identifier. It is roughly the equivalent of a cookie that one sets in a web server - you can use it to determine if you've seen this user before, and what else they've done in your Action, but it does not inheriently relate to any outside account.

Unfortunately, the best solution you have at this point is to use Account Linking which requires you to setup an OAuth2 server. As part of this setup, you will need to create three components:

  1. A login web page for your service. You'll provide the URL for this page to Google as part of Account Linking. When the user accesses your Action, and your action indicates they need to log in, they'll be redirected to this URL on their mobile device. On this page the user will log in - once logged in, you now know their Firebase ID and will create an auth code for this user. You'll then redirect them back to a different URL and pass this auth code (along with some other info) as a parameter.

  2. A token exchange endpoint. Google will call this URL with the auth code above. You'll verify this code, determine who the user is, and send back a unique access token. (You'll also send back a refresh token that Google will use in the same way to get an updated access token.)

  3. An auth token handler in your webhook. When API.AI calls your webhook, it will include the access token as one of the fields in the request. You can use this access token to get the Firebase ID for the user.

One thing to note for the auth code, the access token, and the refresh token is that you'll need to have some way to map from these codes/tokens to the Firebase ID. There are two good ways to do this:

  1. The code/token can be a JSON Web Token (JWT). This takes the Firebase ID, and other information you wish to retain about the user, and puts it in a standard format. It then creates a cryptographic signature, to make sure it hasn't been tampered with, and encodes it in a standard format. When you need to determine the ID from the JWT, you can decode it, verify the signature is valid, and read the value.

  2. Generate a random string and store this in your database against the Firebase ID. When you get the token, you can then look up in your database the ID that this string was assigned to.

There are many additional details about an OAuth implementation and about each of these steps. See https://developers.google.com/actions/identity/oauth2-code-flow for more details.

like image 180
Prisoner Avatar answered Oct 20 '22 04:10

Prisoner