'How to integrate Google Picker with new Google Identity Services JavaScript library

Because of the known issue described in here (https://developers.google.com/identity/sign-in/web/troubleshooting) I want to update my application to be using the new gsi sign-in that uses less cookies than the previous versions and therefore might have the solution for the mentioned error...

My problem is that there's little to no documentation on how to integrate google picker with the new gsi.

I used to use gapi for some picker-related code like even loading the library gapi.load('picker', () => {}). The migration doc says to replace the apis.google.com/js/api.js with the new gsi url, and a lot of other methods such as googleAuth.signIn or gapi.client.init are now to be deprecated by 2023. But then:

  1. How to load picker without gapi available? Or gapi still needs to be imported but will not contain any sign-in related methods?
  2. How will I pass apiKey and scopes to be able to init googlePicker?
  3. For methods such as GoogleAuth.isSignedIn docs simply states "Remove. A user's current sign-in status on Google is unavailable. Users must be signed-in to Google for consent and sign-in moments." what does that even mean? I need to check if user is signed in in order to not show again the popup every time they want to upload a file from gPicker...
  4. Before, we used to have a access_token on the callback of a reloadAuthResponse or a signIn, now how do we get the token?

Sorry for the question being confusing, I'm very confused with everything. Any input helps, thanks!



Solution 1:[1]

I came across https://developers.google.com/identity/oauth2/web/guides/use-token-model through: How to use scoped APIs with (GSI) Google Identity Services

I changed our code to load this script: https://accounts.google.com/gsi/client, and then modified the our "authorize" function (see below) to use window.google.accounts.oauth2.initTokenClient instead of window.gapi.auth2.authorize to get the access_token.

Note that the callback has moved from the second argument of the window.gapi.auth2.authorize function to the callback property of the first argument of the window.google.accounts.oauth2.initTokenClient function.

After calling tokenClient.requestAccessToken() (see below), the callback passed to window.gapi.auth2.authorize is called with an object containing access_token.

const authorize = () =>
-    new Promise(res => window.gapi.auth2.authorize({
-        client_id: GOOGLE_CLIENT_ID,
-        scope: GOOGLE_DRIVE_SCOPE
-    }, res));
+    new Promise(res => {
+        const tokenClient = window.google.accounts.oauth2.initTokenClient({
+            client_id: GOOGLE_CLIENT_ID,
+            scope: GOOGLE_DRIVE_SCOPE,
+            callback: res,
+        });
+        tokenClient.requestAccessToken();
+    });

The way access_token is used was not changed:

new window.google.picker.PickerBuilder().setOAuthToken(access_token)

Solution 2:[2]

@piannone is correct, adding to their answer:

You'll still need to load 'client' code, as you're using authentication. That means you'll still include https://apis.google.com/js/api.js in your list of scripts. Only don't load 'auth2'. So, while you won't do:

 gapi.load('auth2', onAuthApiLoad);
 gapi.load('picker', onPickerApiLoad);

you will need to:

 gapi.load('client', onAuthApiLoad);
 gapi.load('picker', onPickerApiLoad);

(this is instead of directly loading https://accounts.google.com/gsi/client.js I guess.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 piannone
Solution 2 pbuck