title: Google Plus Login - unknown RPC service errors
body: <p>I have integrated Google Plus login on my site, and all was working well until yesterday at around 5pm, my G plus login stopped working in Chrome. No changes to the code, but the button no longer works, the mouse hover does not produce a hand (only a text select), and all of a sudden I am getting several unknown RPC errors in the console:</p>
  
  <pre><code>Uncaught TypeError: Cannot read property 'prototype' of undefined VM2122:6
  Unknown RPC service: _ready cb=gapi.loaded_0:64
  Unknown RPC service: _ready cb=gapi.loaded_0:64
  Unknown RPC service: _resizeMe cb=gapi.loaded_0:64
  </code></pre>
  
  <p>I thought this was related to my Google Plus login button HTML, but I have not been able to track down the problem.  I found <a href="https://stackoverflow.com/questions/17341890/unknown-rpc-service">this topic</a> but it was not helpful, I am not using jQuery to create the button, just pure HTML:</p>
  
  <pre><code>&lt;div id="gConnect"&gt;
      &lt;button class="g-signin"
          data-scope="https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email"
          data-requestvisibleactions="http://schemas.google.com/AddActivity"
          data-clientId="REDACTED"
          data-callback="onSignInCallback"
          data-theme="dark"
          data-cookiepolicy="single_host_origin"&gt;
      &lt;/button&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>and in my JS:</p>
  
  <pre><code>var helper = (function() {
      var BASE_API_PATH = 'plus/v1/';
  
  
      return {
          /**
           * Hides the sign in button and starts the post-authorization operations.
           *
           * @param {Object} authResult An Object which contains the access token and
           *   other authentication information.
           */
  
  
          onSignInCallback: function(authResult) {
            gapi.client.load('plus','v1', function(){
              // $('#authResult').html('Auth Result:&lt;br/&gt;');
              // for (var field in authResult) {
              //   $('#authResult').append(' ' + field + ': ' +
              //       authResult[field] + '&lt;br/&gt;');
              // }
  
  
              if (authResult['access_token']) {
                gapi.auth.setToken(authResult); // Store the returned token.  Unnecessary?
                $('#loggedIn').show('slow');
                $('#gConnect').fadeOut('slow');
                helper.profile();
  
              } else if (authResult['error']) {
                // There was an error, which means the user is not signed in.
                // As an example, you can handle by writing to the console:
                console.log('The user is not signed in.');
                $('#loggedIn').hide('slow');
                $('#gConnect').show();
              }
  
              // console.log('authResult', authResult);
            });
          },
  
          /**
           * Calls the OAuth2 endpoint to disconnect the app for the user.
           */
  
          disconnect: function() {
            // Revoke the access token.
            $.ajax({
              type: 'GET',
              url: 'https://accounts.google.com/o/oauth2/revoke?token=' +
                  gapi.auth.getToken().access_token,
              async: false,
              contentType: 'application/json',
              dataType: 'jsonp',
              success: function(result) {
                console.log('revoke response: ' + result);
                $('#loggedIn').hide();
                $('#profileImg').empty();
                $('#greeting').empty();
                $('#gConnect').show();
              },
              error: function(e) {
                console.log(e);
              }
            });
          },
  
          /**
           * Gets and renders the list of people visible to this app.
           */
          people: function() {
            var request = gapi.client.plus.people.list({
              'userId': 'me',
              'collection': 'visible'
            });
            request.execute(function(people) {
              $('#visiblePeople').empty();
              $('#visiblePeople').append('Number of people visible to this app: ' +
                  people.totalItems + '&lt;br/&gt;');
              for (var personIndex in people.items) {
                person = people.items[personIndex];
                $('#visiblePeople').append('&lt;img src="' + person.image.url + '"&gt;');
              }
            });
          },
  
          /**
           * Gets and renders the currently signed in user's profile data.
           */
          profile: function() {
  
              gapi.client.load('oauth2', 'v2', function() {
  
                  // get email      
                  var request = gapi.client.oauth2.userinfo.get();
                  request.execute(function(obj) {
                    userInfo.setEmail(obj.email);
                  });
  
                  // get profile
                  var request = gapi.client.plus.people.get( {'userId' : 'me'} );
                  request.execute(function(profile) {
                    userInfo.setProfile(profile);
                  });
  
              });
  
          }
      };   
  })();
  
  
  function onSignInCallback(authResult) {
    helper.onSignInCallback(authResult);
  }
  </code></pre>
  
  <p>I haven't been able to find any documentation of changes in the Google+ API or anyone else having this specific problem.  Weird piece of additional info is that I can still login using a mobile browser (Android), but functionality of the app is compromised (beyond the scope of this post).</p>