Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

Commit

Permalink
#37 Google+ login using web browser is rejected on the App Store.
Browse files Browse the repository at this point in the history
  • Loading branch information
EddyVerbruggen committed Mar 5, 2015
1 parent 1646676 commit 18c9f39
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 93 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ Check the [demo app](demo) to get you going quickly, or hurt yourself and follow

Note that none of these methods should be called before [`deviceready`](http://docs.phonegap.com/en/edge/cordova_events_events.md.html#deviceready) has fired.

### isAvailable
You'll want to check this before showing a 'Sign in with Google+' button.

On iOS it will check whether or not the Google+ app is installed. If it's not and you invoke the `login` function,
your app will redirect to Safari [which seems an app rejection reason these days](https://code.google.com/p/google-plus-platform/issues/detail?id=900).

On Android it will check whether or not Google Play Services is available. It's more likely than not that it is.

```javascript
window.plugins.googleplus.isAvailable(
function (available) {
if (available) {
// show the Google+ sign-in button
}
}
);
```

### Login
```javascript
window.plugins.googleplus.login(
Expand Down Expand Up @@ -157,7 +175,8 @@ window.plugins.googleplus.disconnect(
- A: On Android you need to execute the `keytool` steps, see the installation instructions for details.

## 7. Changelog
1.0.0: initial version supporting iOS and Android
1.1.0: Added `isAvailable`, for issue [#37](https://github.com/EddyVerbruggen/cordova-plugin-googleplus/issues/37)
1.0.0: Initial version supporting iOS and Android

## 8. License

Expand Down
6 changes: 6 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ <h1>Google+</h1>
<p class="event received">Device is Ready</p>

<p id="feedback">not logged in</p>
<button onclick="isAvailable()">Available?</button>
<br/><br/>
<button onclick="login()">Login with Google+</button>
<br/><br/>
<button onclick="trySilentLogin()">Try silent login with Google+</button>
Expand All @@ -35,6 +37,10 @@ <h1>Google+</h1>

app.initialize();

function isAvailable() {
window.plugins.googleplus.isAvailable(function(avail) {alert(avail)});
}

function login() {
window.plugins.googleplus.login(
{
Expand Down
28 changes: 0 additions & 28 deletions package.json

This file was deleted.

2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="nl.x-services.plugins.googleplus"
version="1.0.8">
version="1.1.0">

<name>Google+</name>

Expand Down
129 changes: 66 additions & 63 deletions src/android/GooglePlus.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package nl.xservices.plugins;

import java.io.IOException;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.os.AsyncTask;
import android.os.Bundle;

import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
Expand All @@ -22,13 +19,15 @@
import com.google.android.gms.common.api.Status;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;

import org.apache.cordova.*;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

public class GooglePlus extends CordovaPlugin implements ConnectionCallbacks, OnConnectionFailedListener {

public static final String ACTION_IS_AVAILABLE = "isAvailable";
public static final String ACTION_LOGIN = "login";
public static final String ACTION_TRY_SILENT_LOGIN = "trySilentLogin";
public static final String ACTION_LOGOUT = "logout";
Expand Down Expand Up @@ -60,8 +59,11 @@ public boolean execute(String action, CordovaArgs args, CallbackContext callback
this.apiKey = obj.optString(ARGUMENT_ANDROID_KEY, null);
}

if (ACTION_IS_AVAILABLE.equals(action)) {
final boolean avail = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this.cordova.getActivity().getApplicationContext()) == 0;
savedCallbackContext.success("" + avail);

if (ACTION_LOGIN.equals(action)) {
} else if (ACTION_LOGIN.equals(action)) {
this.trySilentLogin = false;
mGoogleApiClient.connect();

Expand All @@ -77,23 +79,24 @@ public boolean execute(String action, CordovaArgs args, CallbackContext callback
loggingOut = true;
mGoogleApiClient = buildGoogleApiClient();
mGoogleApiClient.connect();
} catch (IllegalStateException e) {

} catch (IllegalStateException ignore) {
}
savedCallbackContext.success("logged out");

} else if (ACTION_DISCONNECT.equals(action)) {
disconnect();
} else {
return false;
}
return true;
}

private void disconnect() {
try {
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
public void onResult(Status status) {
// mGoogleApiClient is now disconnected and access has been revoked.
// Don't care if it was disconnected already (status != success).
mGoogleApiClient = buildGoogleApiClient();
Expand All @@ -107,63 +110,63 @@ public void onResult(Status status) {

private GoogleApiClient buildGoogleApiClient() {
return new GoogleApiClient.Builder(webView.getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.build();
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.build();
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private void resolveToken(final String email, final JSONObject result) {
final Context context = this.cordova.getActivity().getApplicationContext();

cordova.getThreadPool().execute(new Runnable() {
public void run() {
String scope = null;
String token = null;
public void run() {
String scope = null;
String token = null;

try {
if (GooglePlus.this.webKey != null){
// Retrieve server side tokens
scope = "audience:server:client_id:" + GooglePlus.this.webKey;
token = GoogleAuthUtil.getToken(context, email, scope);
result.put("idToken", token);
} else if (GooglePlus.this.apiKey != null) {
// Retrieve the oauth token with offline mode
scope = "oauth2:server:client_id:" + GooglePlus.this.apiKey;
scope += ":api_scope:" + Scopes.PLUS_LOGIN;
token = GoogleAuthUtil.getToken(context, email, scope);
result.put("oauthToken", token);
} else {
// Retrieve the oauth token with offline mode
scope = "oauth2:" + Scopes.PLUS_LOGIN;
token = GoogleAuthUtil.getToken(context, email, scope);
result.put("oauthToken", token);
}
}
catch (UserRecoverableAuthException userAuthEx) {
// Start the user recoverable action using the intent returned by
// getIntent()
cordova.getActivity().startActivityForResult(userAuthEx.getIntent(),
Activity.RESULT_OK);
return;
try {
if (GooglePlus.this.webKey != null){
// Retrieve server side tokens
scope = "audience:server:client_id:" + GooglePlus.this.webKey;
token = GoogleAuthUtil.getToken(context, email, scope);
result.put("idToken", token);
} else if (GooglePlus.this.apiKey != null) {
// Retrieve the oauth token with offline mode
scope = "oauth2:server:client_id:" + GooglePlus.this.apiKey;
scope += ":api_scope:" + Scopes.PLUS_LOGIN;
token = GoogleAuthUtil.getToken(context, email, scope);
result.put("oauthToken", token);
} else {
// Retrieve the oauth token with offline mode
scope = "oauth2:" + Scopes.PLUS_LOGIN;
token = GoogleAuthUtil.getToken(context, email, scope);
result.put("oauthToken", token);
}
catch (IOException e) {
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
return;
} catch (GoogleAuthException e) {
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
return;
} catch (JSONException e) {
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
return;
}

savedCallbackContext.success(result);
}
});
catch (UserRecoverableAuthException userAuthEx) {
// Start the user recoverable action using the intent returned by
// getIntent()
cordova.getActivity().startActivityForResult(userAuthEx.getIntent(),
Activity.RESULT_OK);
return;
}
catch (IOException e) {
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
return;
} catch (GoogleAuthException e) {
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
return;
} catch (JSONException e) {
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
return;
}

savedCallbackContext.success(result);
}
});
}

/**
Expand Down Expand Up @@ -215,12 +218,12 @@ public void onConnected(Bundle connectionHint) {
// same as iOS values
private static String getGender(int gender) {
switch (gender) {
case 0:
return "male";
case 1:
return "female";
default:
return "other";
case 0:
return "male";
case 1:
return "female";
default:
return "other";
}
}

Expand Down
1 change: 1 addition & 0 deletions src/ios/GooglePlus.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@property (nonatomic, copy) NSString* callbackId;
@property (nonatomic, assign) BOOL isSigningIn;

- (void) isAvailable:(CDVInvokedUrlCommand*)command;
- (void) login:(CDVInvokedUrlCommand*)command;
- (void) trySilentLogin:(CDVInvokedUrlCommand*)command;
- (void) logout:(CDVInvokedUrlCommand*)command;
Expand Down
8 changes: 8 additions & 0 deletions src/ios/GooglePlus.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ - (BOOL)identity_application: (UIApplication *)application

@implementation GooglePlus

// If this returns false, you better not call the login function because of likely app rejection by Apple,
// see https://code.google.com/p/google-plus-platform/issues/detail?id=900
- (void) isAvailable:(CDVInvokedUrlCommand*)command {
BOOL appInstalled = [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"gplus://"]];
CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:appInstalled];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void) login:(CDVInvokedUrlCommand*)command {
self.isSigningIn = YES;
[[self getGooglePlusSignInObject:command] authenticate];
Expand Down
4 changes: 4 additions & 0 deletions www/GooglePlus.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
function GooglePlus() {
}

GooglePlus.prototype.isAvailable = function (callback) {
cordova.exec(callback, null, "GooglePlus", "isAvailable", []);
};

GooglePlus.prototype.login = function (options, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, "GooglePlus", "login", [options]);
};
Expand Down

0 comments on commit 18c9f39

Please sign in to comment.