18

I am trying to integrate Google Sign In (link) using React.
I found a question that has solved this in past Using google sign in button with react 2

I replicated the same steps as mentioned. In my index.html I do

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script>
    <script type="text/javascript">
        function triggerGoogleLoaded() {
            console.log("google event loaded");
            window.dispatchEvent(new Event('google-loaded'));
        }
    </script>

Then my Component looks like

var LoginButton = React.createClass({

    onSignIn: function(googleUser) {
        console.log("user signed in"); // plus any other logic here
    },

    renderGoogleLoginButton: function() {
        console.log('rendering google signin button');
        gapi.signin2.render('my-signin2', {
            'scope': 'https://www.googleapis.com/auth/plus.login',
            'width': 200,
            'height': 50,
            'longtitle': true,
            'theme': 'light',
            'onsuccess': this.onSignIn
        })
    },

    componentDidMount: function() {
        window.addEventListener('google-loaded',this.renderGoogleLoginButton);
    },

    render: function() {
        let displayText = "Sign in with Google";
        return (
            <div class="g-signin2" data-onsuccess="onSignIn"></div>
        );
    }

});

export default LoginButton;

When I run the program using yarn start, I get

/Users/Harit.Himanshu/bl/sources/webs/google-login/src/LoginButton.js
  11:9   error    'gapi' is not defined                             no-undef
  26:13  warning  'displayText' is assigned a value but never used  no-unused-vars

✖ 2 problems (1 error, 1 warning)

The complete source code is available at https://github.com/hhimanshu/google-login-with-react

Could someone please help me understand my mistake?

Thanks

Community
  • 1
  • 1
daydreamer
  • 87,243
  • 191
  • 450
  • 722

5 Answers5

25

It looks to me like you're loading the google apis as a script tag, which we'd expect to set window.gapi to the google api. However, you're then running eslint or some other checker, and that has no idea that window.gapi is supposed to exist. It's failing because it sees you using an undeclared variable.

A cheap fix is to tell Eslint that you know what you are doing;

/* global gapi */

Put this at the top of your file and eslint will treat gapi as a known global variable.

Steve Cooper
  • 20,542
  • 15
  • 71
  • 88
  • Thanks @steve, this has helped me to get get the button, now I am stuck with https://stackoverflow.com/questions/43767485/react-unable-to-perform-google-sign-in-no-errors-are-visible, do you know where am I making mistake? – daydreamer May 03 '17 at 18:27
5

This worked for me. Put it in componentDidMount or constructor:

componentDidMount() {
    window.gapi.load('auth2', () => {
        // Retrieve the singleton for the GoogleAuth library and set up the client.
        this.auth2 = window.gapi.auth2.init({
            client_id: '436676563344-.apps.googleusercontent.com',
            cookiepolicy: 'single_host_origin',
        });

        this.auth2.attachClickHandler(this.refs.googleButton, {},
            (googleUser) => {
                this.googleLogin(googleUser.getBasicProfile());
            }, (error) => {

            });
    });
}
Giang Le
  • 6,446
  • 4
  • 23
  • 26
5

You can also try the package gapi-script, this package provides the gapi instantly, so you don't have to wait any script to load, just import it and use:

import { gapi } from 'gapi-script';
Lucas Andrade
  • 4,315
  • 5
  • 29
  • 50
  • Not a good solution since gapi script is updated by Google dynamically and this is just a hard copy of the script. You can end up with an outdated version of the script and your application may stop working. – jantobola Nov 17 '20 at 13:07
  • Yes that's true and I agree with you, I don't recommend this package for companies and enterprise projects, only to small projects to study and etc. – Lucas Andrade Nov 17 '20 at 13:49
  • 1
    The package was updated, now there is a function to download and use the real script from google's link. – Lucas Andrade Mar 24 '21 at 12:39
2

Make sure that you’re not using async defer, which will cause race conditions between window.gapi.someMethod() and your script loading

In short, remove async defer from your script tag in your index.html.

before

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded" async defer></script>

after

<script src="https://apis.google.com/js/platform.js?onload=triggerGoogleLoaded"></script>
Yang
  • 618
  • 6
  • 9
0

I had a simillar issue.

I use 'react-snap' for SEO. It blocked me to use 'gapi'. I found navigator.userAgent 'ReactSnap'.

if (navigator.userAgent !== 'ReactSnap') {
    // some code to dynamically load a script
    let myScript = document.createElement('script')
    myScript.setAttribute('src', 'https://apis.google.com/js/platform.js')
    document.body.appendChild(myScript)
}

I solved a problem. It works very well.

Meloman
  • 3,558
  • 3
  • 41
  • 51
imki123
  • 58
  • 7