目次

googleサインイン

Expo.Google.logInAsync を使ったGoogleサインイン。

Error: cannot set promise - some async operation is still in progress

Error: cannot set promise - some async operation is still in progress

SDK32になると、使えなくなった。
現在対応検討中。
それまでSDK31を使う。

TypeError: Cannot read property 'Google' of undefined

error [TypeError: Cannot read property 'Google' of undefined]

import Expo from “expo”は使えなくなった。
import * as Expo from “expo”を使う。

設定手順

Google認証情報作成(Google developers consoleで認証情報を作成)

Google developers consoleで任意のプロジェクトを作成する。

認証情報画面を開き、認証情報を作成でOAuthクライアントIDを作成する。

SHA-1 署名証明書フィンガープリントを発行する。

> openssl rand -base64 32 | openssl sha1 -c

発行したフィンガープリントを設定し、
パッケージ名にはhost.exp.exponentを設定する。

発行されたクライアントIDをアプリに設定する。

React のコード

認証

    try {
      const result = await Expo.Google.logInAsync({
        androidClientId: androidClientId,
          scopes: ["profile", "email","https://www.googleapis.com/auth/spreadsheets"]
      })
      if (result.type === "success") {
        console.log(result)
        this.setState({
          signedIn: true,
          name: result.user.name,
          photoUrl: result.user.photoUrl,
          accessToken:result.accessToken,
          refreshToken:result.refreshToken,
        })
        ・・・

リフレッシュトークンを使ってアクセストークンを更新

    try {
      let url= "https://accounts.google.com/o/oauth2/token"
      let bodyString = JSON.stringify({
        client_id:androidClientId ,
        refresh_token:this.state.refreshToken ,
        grant_type:"refresh_token" ,
      })

      const result = await fetch(url, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: bodyString
      });

      let responseJson = await result.json();

      if (responseJson.access_token !== undefined) {
        //ステート更新
        this.setState({
          accessToken : responseJson.access_token
        })
        ・・・

userinfo取得

        let userInfoResponse = await fetch('https://www.googleapis.com/userinfo/v2/me', {
            headers: { Authorization: `Bearer ${value}` },
        });
        let userInfo = await userInfoResponse.json();
        console.log(userInfo)
        this.setState({
          signedIn: true,
          name: userInfo.name,
          photoUrl: userInfo.picture
        })

エラー1 (crash)

apkにしたときオプションにbehavior:webだとクラッシュする。
systemだと内部ブラウザが立ち上がり、ログインしても何もかえってこない。

下記ドキュメントをよくみてみるとandroidStandaloneAppClientIdに変更する必要がる。
Google

・androidClientId (string) -- The Android client id registered with Google for use in the Expo client app.
  ⇒expoのデバッグ用

・androidStandaloneAppClientId (string) -- The Android client id registered with Google for use in a standalone app.
  ⇒apkを作るときにはこちらで設定する。
    try {
      const result = await Expo.Google.logInAsync({
        androidStandaloneAppClientId: androidClientId,
          scopes: ["profile", "email","https://www.googleapis.com/auth/spreadsheets"],
          behavior: 'web'
      })
      if (result.type === "success") {
      ・・・

エラー2 (redirect_uri_mismatch)

エラー1の設定変更(androidStandaloneAppClientIdとbehaviorの変更)により、apkでも外部ブラウザにとぶようになるが、redirect_uriのエラーがでる場合がある。

expoのテストではパッケージ名に「host.exp.exponent」を設定していた箇所に、実際のアプリのパッケージ名を設定する。
下記の場合は「com.nekotype.expo.meomry2」

redirect_uri=com.nekotype.expo.meomry2:/oauthredirect
client_id=xxxxx.apps.googleusercontent.com
response_type=code
state=xxxx
scope=profile email https://www.googleapis.com/auth/spreadsheets
code_challenge=xxxx
code_challenge_method=xx
That’s all we know.