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

Commit 18c9f39

Browse files
#37 Google+ login using web browser is rejected on the App Store.
1 parent 1646676 commit 18c9f39

File tree

8 files changed

+106
-93
lines changed

8 files changed

+106
-93
lines changed

Diff for: README.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,24 @@ Check the [demo app](demo) to get you going quickly, or hurt yourself and follow
7070

7171
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.
7272

73+
### isAvailable
74+
You'll want to check this before showing a 'Sign in with Google+' button.
75+
76+
On iOS it will check whether or not the Google+ app is installed. If it's not and you invoke the `login` function,
77+
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).
78+
79+
On Android it will check whether or not Google Play Services is available. It's more likely than not that it is.
80+
81+
```javascript
82+
window.plugins.googleplus.isAvailable(
83+
function (available) {
84+
if (available) {
85+
// show the Google+ sign-in button
86+
}
87+
}
88+
);
89+
```
90+
7391
### Login
7492
```javascript
7593
window.plugins.googleplus.login(
@@ -157,7 +175,8 @@ window.plugins.googleplus.disconnect(
157175
- A: On Android you need to execute the `keytool` steps, see the installation instructions for details.
158176

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

162181
## 8. License
163182

Diff for: demo/index.html

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ <h1>Google+</h1>
1919
<p class="event received">Device is Ready</p>
2020

2121
<p id="feedback">not logged in</p>
22+
<button onclick="isAvailable()">Available?</button>
23+
<br/><br/>
2224
<button onclick="login()">Login with Google+</button>
2325
<br/><br/>
2426
<button onclick="trySilentLogin()">Try silent login with Google+</button>
@@ -35,6 +37,10 @@ <h1>Google+</h1>
3537

3638
app.initialize();
3739

40+
function isAvailable() {
41+
window.plugins.googleplus.isAvailable(function(avail) {alert(avail)});
42+
}
43+
3844
function login() {
3945
window.plugins.googleplus.login(
4046
{

Diff for: package.json

-28
This file was deleted.

Diff for: plugin.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
33
xmlns:android="http://schemas.android.com/apk/res/android"
44
id="nl.x-services.plugins.googleplus"
5-
version="1.0.8">
5+
version="1.1.0">
66

77
<name>Google+</name>
88

Diff for: src/android/GooglePlus.java

+66-63
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package nl.xservices.plugins;
22

3-
import java.io.IOException;
4-
53
import android.app.Activity;
64
import android.app.PendingIntent;
75
import android.content.Context;
86
import android.content.Intent;
97
import android.content.IntentSender;
10-
import android.os.AsyncTask;
118
import android.os.Bundle;
12-
139
import com.google.android.gms.auth.GoogleAuthException;
1410
import com.google.android.gms.auth.GoogleAuthUtil;
1511
import com.google.android.gms.auth.UserRecoverableAuthException;
1612
import com.google.android.gms.common.ConnectionResult;
13+
import com.google.android.gms.common.GooglePlayServicesUtil;
1714
import com.google.android.gms.common.Scopes;
1815
import com.google.android.gms.common.api.GoogleApiClient;
1916
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
@@ -22,13 +19,15 @@
2219
import com.google.android.gms.common.api.Status;
2320
import com.google.android.gms.plus.Plus;
2421
import com.google.android.gms.plus.model.people.Person;
25-
2622
import org.apache.cordova.*;
2723
import org.json.JSONException;
2824
import org.json.JSONObject;
2925

26+
import java.io.IOException;
27+
3028
public class GooglePlus extends CordovaPlugin implements ConnectionCallbacks, OnConnectionFailedListener {
3129

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

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

64-
if (ACTION_LOGIN.equals(action)) {
66+
} else if (ACTION_LOGIN.equals(action)) {
6567
this.trySilentLogin = false;
6668
mGoogleApiClient.connect();
6769

@@ -77,23 +79,24 @@ public boolean execute(String action, CordovaArgs args, CallbackContext callback
7779
loggingOut = true;
7880
mGoogleApiClient = buildGoogleApiClient();
7981
mGoogleApiClient.connect();
80-
} catch (IllegalStateException e) {
81-
82+
} catch (IllegalStateException ignore) {
8283
}
8384
savedCallbackContext.success("logged out");
8485

8586
} else if (ACTION_DISCONNECT.equals(action)) {
8687
disconnect();
88+
} else {
89+
return false;
8790
}
8891
return true;
8992
}
9093

9194
private void disconnect() {
9295
try {
9396
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
94-
.setResultCallback(new ResultCallback<Status>() {
97+
.setResultCallback(new ResultCallback<Status>() {
9598
@Override
96-
public void onResult(Status status) {
99+
public void onResult(Status status) {
97100
// mGoogleApiClient is now disconnected and access has been revoked.
98101
// Don't care if it was disconnected already (status != success).
99102
mGoogleApiClient = buildGoogleApiClient();
@@ -107,63 +110,63 @@ public void onResult(Status status) {
107110

108111
private GoogleApiClient buildGoogleApiClient() {
109112
return new GoogleApiClient.Builder(webView.getContext())
110-
.addConnectionCallbacks(this)
111-
.addOnConnectionFailedListener(this)
112-
.addApi(Plus.API, Plus.PlusOptions.builder().build())
113-
.addScope(Plus.SCOPE_PLUS_LOGIN)
114-
.addScope(Plus.SCOPE_PLUS_PROFILE)
115-
.build();
113+
.addConnectionCallbacks(this)
114+
.addOnConnectionFailedListener(this)
115+
.addApi(Plus.API, Plus.PlusOptions.builder().build())
116+
.addScope(Plus.SCOPE_PLUS_LOGIN)
117+
.addScope(Plus.SCOPE_PLUS_PROFILE)
118+
.build();
116119
}
117120

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

122125
cordova.getThreadPool().execute(new Runnable() {
123-
public void run() {
124-
String scope = null;
125-
String token = null;
126+
public void run() {
127+
String scope = null;
128+
String token = null;
126129

127-
try {
128-
if (GooglePlus.this.webKey != null){
129-
// Retrieve server side tokens
130-
scope = "audience:server:client_id:" + GooglePlus.this.webKey;
131-
token = GoogleAuthUtil.getToken(context, email, scope);
132-
result.put("idToken", token);
133-
} else if (GooglePlus.this.apiKey != null) {
134-
// Retrieve the oauth token with offline mode
135-
scope = "oauth2:server:client_id:" + GooglePlus.this.apiKey;
136-
scope += ":api_scope:" + Scopes.PLUS_LOGIN;
137-
token = GoogleAuthUtil.getToken(context, email, scope);
138-
result.put("oauthToken", token);
139-
} else {
140-
// Retrieve the oauth token with offline mode
141-
scope = "oauth2:" + Scopes.PLUS_LOGIN;
142-
token = GoogleAuthUtil.getToken(context, email, scope);
143-
result.put("oauthToken", token);
144-
}
145-
}
146-
catch (UserRecoverableAuthException userAuthEx) {
147-
// Start the user recoverable action using the intent returned by
148-
// getIntent()
149-
cordova.getActivity().startActivityForResult(userAuthEx.getIntent(),
150-
Activity.RESULT_OK);
151-
return;
130+
try {
131+
if (GooglePlus.this.webKey != null){
132+
// Retrieve server side tokens
133+
scope = "audience:server:client_id:" + GooglePlus.this.webKey;
134+
token = GoogleAuthUtil.getToken(context, email, scope);
135+
result.put("idToken", token);
136+
} else if (GooglePlus.this.apiKey != null) {
137+
// Retrieve the oauth token with offline mode
138+
scope = "oauth2:server:client_id:" + GooglePlus.this.apiKey;
139+
scope += ":api_scope:" + Scopes.PLUS_LOGIN;
140+
token = GoogleAuthUtil.getToken(context, email, scope);
141+
result.put("oauthToken", token);
142+
} else {
143+
// Retrieve the oauth token with offline mode
144+
scope = "oauth2:" + Scopes.PLUS_LOGIN;
145+
token = GoogleAuthUtil.getToken(context, email, scope);
146+
result.put("oauthToken", token);
152147
}
153-
catch (IOException e) {
154-
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
155-
return;
156-
} catch (GoogleAuthException e) {
157-
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
158-
return;
159-
} catch (JSONException e) {
160-
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
161-
return;
162-
}
163-
164-
savedCallbackContext.success(result);
165148
}
166-
});
149+
catch (UserRecoverableAuthException userAuthEx) {
150+
// Start the user recoverable action using the intent returned by
151+
// getIntent()
152+
cordova.getActivity().startActivityForResult(userAuthEx.getIntent(),
153+
Activity.RESULT_OK);
154+
return;
155+
}
156+
catch (IOException e) {
157+
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
158+
return;
159+
} catch (GoogleAuthException e) {
160+
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
161+
return;
162+
} catch (JSONException e) {
163+
savedCallbackContext.error("Failed to retrieve token: " + e.getMessage());
164+
return;
165+
}
166+
167+
savedCallbackContext.success(result);
168+
}
169+
});
167170
}
168171

169172
/**
@@ -215,12 +218,12 @@ public void onConnected(Bundle connectionHint) {
215218
// same as iOS values
216219
private static String getGender(int gender) {
217220
switch (gender) {
218-
case 0:
219-
return "male";
220-
case 1:
221-
return "female";
222-
default:
223-
return "other";
221+
case 0:
222+
return "male";
223+
case 1:
224+
return "female";
225+
default:
226+
return "other";
224227
}
225228
}
226229

Diff for: src/ios/GooglePlus.h

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@property (nonatomic, copy) NSString* callbackId;
77
@property (nonatomic, assign) BOOL isSigningIn;
88

9+
- (void) isAvailable:(CDVInvokedUrlCommand*)command;
910
- (void) login:(CDVInvokedUrlCommand*)command;
1011
- (void) trySilentLogin:(CDVInvokedUrlCommand*)command;
1112
- (void) logout:(CDVInvokedUrlCommand*)command;

Diff for: src/ios/GooglePlus.m

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ - (BOOL)identity_application: (UIApplication *)application
3232

3333
@implementation GooglePlus
3434

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

Diff for: www/GooglePlus.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
function GooglePlus() {
22
}
33

4+
GooglePlus.prototype.isAvailable = function (callback) {
5+
cordova.exec(callback, null, "GooglePlus", "isAvailable", []);
6+
};
7+
48
GooglePlus.prototype.login = function (options, successCallback, errorCallback) {
59
cordova.exec(successCallback, errorCallback, "GooglePlus", "login", [options]);
610
};

0 commit comments

Comments
 (0)