I’m trying the Android app using Firebase.
I need to authenticate by Google Client API in order to use Firebase.
But, I can’t authenticate by Google Client API.
In following code, GoogleSignInResult.isSuccess() returns false.
GoogleSignInResult.getState().getStateMessage() returns null. So, I don’t know why Google authentication failed.
Is there something you have to do when using Google authentication?
Thanks in advance.
Note:
I can authenticate by Google Client API when I install release.apk by the command “add install release.apk”.
But I cannot authenticate when I install via Google Play Store( not BETA but RELEASE).
Screenshot:
After login button pressed(login button:lower right button)
Code:
In onActivityResult, GoogleSignInResult.isSuccess() returns false.
public class LoginActivity extends AppCompatActivity {
private static final int REQUEST_CODE_SIGN_IN = 9001;
private FirebaseAuth firebaseAuth;
public static GoogleApiClient googleAPIClient;
private DatabaseReference usersRef;
private ProgressDialog progressDialog;
private GoogleApiClient.OnConnectionFailedListener onConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(LoginActivity.this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
System.out.println("*** LoginActivity.onCreate - start");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
try {
progressDialog = new ProgressDialog(this);
GoogleSignInOptions options = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
googleAPIClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, onConnectionFailedListener)
.addApi(Auth.GOOGLE_SIGN_IN_API, options)
.build();
firebaseAuth = FirebaseAuth.getInstance();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("*** LoginActivity.onCreate - start");
}
#Override
public void onStop() {
System.out.println("LoginActivity.onStop - start");
if (null != usersRef) {
usersRef.removeEventListener(valueEventlistener);
}
super.onStop();
}
public void onCancelButtonClick(View view) {
finish();
}
public void onLoginButtonClick(View view) {
System.out.println("*** LoginActivity.onLoginButtonClick - start");
Intent intent = Auth.GoogleSignInApi.getSignInIntent(googleAPIClient);
startActivityForResult(intent, REQUEST_CODE_SIGN_IN);
System.out.println("*** LoginActivity.onLoginButtonClick - end");
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
System.out.println("*** LoginActivity.onActivityResult - start");
if (requestCode == REQUEST_CODE_SIGN_IN) {
System.out.println("*** LoginActivity.onActivityResult - in if");
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
System.out.println("*** LoginActivity.onActivityResult - in if success");
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthWithGoogle(account);
} else {
System.out.println("*** LoginActivity.onActivityResult - in if error");
System.out.println("*** LoginActivity.onActivityResult - in if error state:" + result.getStatus().getStatusMessage());
Toast.makeText(LoginActivity.this, "Error:" + result.getStatus().getStatusMessage(), Toast.LENGTH_SHORT).show();
}
}
System.out.println("*** LoginActivity.onActivityResult - end");
}
public void firebaseAuthWithGoogle(GoogleSignInAccount account) {
// firebase authentication
}
Have you added your Release version SHA1 Fingerprint in the Firebase Project Setting?
I am trying to connect my App to Google Play Services, for to add games achievements, but it doesn´t connect. It returns me this message:
Failed to sign in. Please check your network connection and try again.
I reinstalled Google Services, and it didn´t fix the problem.
Here is my code.
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
{
public static GoogleApiClient googleApiClient;
private static int RC_SIGN_IN = 9001;
private boolean mResolvingConnectionFailure = false;
private boolean mAutoStartSignInflow = true;
private boolean mSignInClicked = false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
}
#Override
protected void onStart() {
try
{
super.onStart();
googleApiClient.connect();
}catch (Exception e)
{
e.printStackTrace();
}
}
#Override
protected void onStop() {
try
{
super.onStop();
googleApiClient.disconnect();
}catch (Exception e)
{
e.printStackTrace();
}
}
protected void onActivityResult(int requestCode, int resultCode,Intent intent)
{
if (requestCode == RC_SIGN_IN)
{
mSignInClicked = false;
mResolvingConnectionFailure = false;
if (resultCode == RESULT_OK)
{
googleApiClient.connect();
}
else
{
BaseGameUtils.showActivityResultError(this, requestCode, resultCode, R.string.error_conectar_google_juegos2);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putBoolean("STATE_RESOLVING_ERROR", false);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult)
{
if (mResolvingConnectionFailure)
{
return;
}
if (mSignInClicked || mAutoStartSignInflow)
{
mAutoStartSignInflow = false;
mSignInClicked = false;
mResolvingConnectionFailure = true;
if (!BaseGameUtils.resolveConnectionFailure(this,googleApiClient, connectionResult,RC_SIGN_IN, R.string.error_conectar_google_juegos1))
{
mResolvingConnectionFailure = false;
}
}
}
}
The execution flow is the next:
onCreate()
onStart()
onConnectionFailed()
onSaveinstanceState()
It asks for my Google Account
onActivityResult()
Here it goes to the "ELSE" of the onActivityResult().
When it fails, it shows the message I said before.
I have good internet connection on my device, and I use Android Games of Google Games with no problem. What can be happening?
Thank you so much.
I've been looking for a solution to this and I came across several answers that didn't fit the use-case. The sample code from Google works fine if imported as is, but the code sits in an Activity and is messy if you want to integrate into a real project where the code would ideally be in a fragment.
The issue is with the enableAutoManage functionality and what to do in the fresh install case where the googleApiClient is built but the authentication/account-pick screen is not yet done and you end up with connection failed on the googleApiClient. I'm going to answer this in full, below.
Here is a sample Activity that will load the GoogleFit_Fragment into the FrameLayout:
public class Main_Activity extends AppCompatActivity {
public static int USER_AUTHORISED_REQUEST_CODE = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
This will load the GoogleFit_Fragment into the FrameLayout,
which will cause the buildFitnessClient() function to be called from the Fragment,
which will cause this Activity to popup the authentication screen
*/
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.fade_in, R.anim.fade_out)
.replace(R.id.fragment_container, new GoogleFit_Fragment()).commit();
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
/*
The result of the account chooser is here,
send it to the fragment so we can handle it inside
*/
fragmentReplace.onActivityResult(USER_AUTHORISED_REQUEST_CODE, resultCode, data);
}
}
The GoogleFit_Fragment:
public class GoogleFit_Fragment extends Fragment {
public static final String TAG = "Sample";
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 1;
private GoogleApiClient googleApiFitnessClient;
private OnDataPointListener mListener;
private View fragmentView;
private Activity parentActivity;
#Override
public void onStop() {
super.onStop();
if (googleApiFitnessClient != null) {
Log.d(TAG, "onStop REACHED, client not null and is connected");
googleApiFitnessClient.stopAutoManage(getActivity());
googleApiFitnessClient.disconnect();
}
}
#Override
public void onResume() {
super.onResume();
if (googleApiFitnessClient != null) {
Log.d(TAG, "onResume REACHED, client not null");
googleApiFitnessClient.stopAutoManage(getActivity());
googleApiFitnessClient.disconnect();
googleApiFitnessClient.connect();
} else {
Log.d(TAG, "onResume REACHED, client null, buildingClient");
buildFitnessClient();
googleApiFitnessClient.connect();
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof Activity) {
parentActivity = (Activity) context;
}
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
fragmentView = inflater.inflate(R.layout.fragment_google_fit, container, false);
initializeLogging();
if (!checkPermissions()) {
requestPermissions();
}
return fragmentView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Main_Activity.USER_AUTHORISED_REQUEST_CODE && googleApiFitnessClient != null) {
Log.d(TAG, "Activity result finished authorissation, disconnect the client and reconnect");
googleApiFitnessClient.stopAutoManage(getActivity());
googleApiFitnessClient.disconnect();
googleApiFitnessClient.connect();
}
}
private void buildFitnessClient() {
googleApiFitnessClient = new GoogleApiClient.Builder(parentActivity)
.addApi(Fitness.SENSORS_API)
// .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
// .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ_WRITE))
// .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs.
findFitnessDataSources();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i
== GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG,
"Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed! " + connectionResult.getErrorMessage());
}
}
)
.enableAutoManage((FragmentActivity) parentActivity, 0, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Google Play services connection failed. Cause: " +
result.toString());
}
})
.build();
}
private void findFitnessDataSources() {
// Note: Fitness.SensorsApi.findDataSources() requires the ACCESS_FINE_LOCATION permission.
Fitness.SensorsApi.findDataSources(googleApiFitnessClient, new DataSourcesRequest.Builder()
// At least one datatype must be specified.
.setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
// Can specify whether data type is raw or derived.
.setDataSourceTypes(DataSource.TYPE_RAW)
.build())
.setResultCallback(new ResultCallback<DataSourcesResult>() {
#Override
public void onResult(DataSourcesResult dataSourcesResult) {
Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
for (DataSource dataSource : dataSourcesResult.getDataSources()) {
Log.i(TAG, "Data source found: " + dataSource.toString());
Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());
//Let's register a listener to receive Activity data!
if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE)
&& mListener == null) {
Log.i(TAG, "Data source for " + dataSource.getDataType() + " found! Registering.");
registerFitnessDataListener(dataSource,
DataType.TYPE_STEP_COUNT_CUMULATIVE);
}
}
}
});
}
/**
* Register a listener with the Sensors API for the provided {#link DataSource} and
* {#link DataType} combo.
*/
private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {
mListener = new OnDataPointListener() {
#Override
public void onDataPoint(DataPoint dataPoint) {
for (Field field : dataPoint.getDataType().getFields()) {
Value val = dataPoint.getValue(field);
Log.i(TAG, "Detected DataPoint field: " + field.getName());
Log.i(TAG, "Detected DataPoint value: " + val);
}
}
};
Fitness.SensorsApi.add(
googleApiFitnessClient,
new SensorRequest.Builder()
.setDataSource(dataSource) // Optional but recommended for custom data sets.
.setDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE) // Can't be omitted.
.setSamplingRate(1, TimeUnit.SECONDS)
.build(),
mListener)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
Log.i(TAG, "Listener registered!");
} else {
Log.i(TAG, "Listener not registered.");
}
}
});
}
private void initializeLogging() {
/*
Not really needed, you can just log to Logcat without having a view in this fragment
*/
LogWrapper logWrapper = new LogWrapper();
Log.setLogNode(logWrapper);
MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
logWrapper.setNext(msgFilter);
LogView logView = (LogView) fragmentView.findViewById(R.id.sample_logview);
logView.setTextAppearance(parentActivity, R.style.Log);
logView.setBackgroundColor(Color.WHITE);
msgFilter.setNext(logView);
Log.i(TAG, "Ready");
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(parentActivity,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(parentActivity,
Manifest.permission.ACCESS_FINE_LOCATION);
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
Snackbar.make(
fragmentView.findViewById(R.id.main_activity_view),
R.string.permission_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
#Override
public void onClick(View view) {
// Request permission
ActivityCompat.requestPermissions(parentActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BODY_SENSORS},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
})
.show();
} else {
Log.i(TAG, "Requesting permission");
ActivityCompat.requestPermissions(parentActivity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BODY_SENSORS},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
buildFitnessClient();
} else {
Snackbar.make(
fragmentView.findViewById(R.id.main_activity_view),
R.string.permission_denied_explanation,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.settings, new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.show();
}
}
}
}
Flow:
Launch app
Google API client is built, causing a connection failed callback, but also causing the Account Picker dialog to appear
Account is picked, onActivityResult from Activity is called, result is sent to onActivityResult in Fragment
Google API client is restarted (stopAutoManage, disconnect, connect)
Logging starts STEP_COUNT_CUMULATIVE or any other data type you choose
This works and is tested a lot, please ask if you're unsure of anything
I'm trying to implement Google+ login in my application but it won't work.
Everytime I click log in, the onConnectionFailed gets called as soon as I choose the account.
Could someone please let me know what's wrong?
public class LoginActivity extends ActionBarActivity
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener{
/*
Variables
*/
/* Request code used to invoke sign in user interactions. */
private static final int RC_SIGN_IN = 0;
/* Client used to interact with Google APIs. */
private GoogleApiClient mGoogleApiClient;
/* A flag indicating that a PendingIntent is in progress and prevents
* us from starting further intents.
*/
private boolean mIntentInProgress;
/*
* True if the sign-in button was clicked. When true, we know to resolve all
* issues preventing sign-in without waiting.
*/
private boolean mSignInClicked;
/*
Lifecycle
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
// Sign in button click listener
findViewById(R.id.googleSignInButton).setOnClickListener(this);
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/*
Callbacks
*/
#Override
public void onClick(View v) {
if (v.getId() == R.id.googleSignInButton && !mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
mGoogleApiClient.connect();
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i("TAG", "onConnectionFailed");
if (!mIntentInProgress) {
if (mSignInClicked && connectionResult.hasResolution()) {
// The user has already clicked 'sign-in' so we attempt to resolve all
// errors until the user is signed in, or they cancel.
try {
connectionResult.startResolutionForResult(this, RC_SIGN_IN);
mIntentInProgress = true;
} catch (IntentSender.SendIntentException e) {
// The intent was canceled before it was sent. Return to the default
// state and attempt to connect to get an updated ConnectionResult.
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i("TAG", "onConnected");
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int i) {
Log.i("TAG", "onConnectionSuspended");
mGoogleApiClient.connect();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.reconnect();
}
}
}
}
I even downloaded official Google sample for login and I get the same error. It just won't log in and connect.
I have good connection (even wifi) and I tried it on multiple phones.
It just might be an issue with the key you are using.
Go to your google api's console Try Generating a new Cient id with your
SHA1 obtained from debug.keystore and try Login again.I'm sure it'll help solve your issue.
I want to do the post on google-plus through my app. I am using this code for that but it not working it giving me message that I couldn't post the message and I also having a doubt where i will use my clientId?.please help me.
public class MainActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final String TAG = "ExampleActivity";
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private ProgressDialog mConnectionProgressDialog;
private PlusClient mPlusClient;
private ConnectionResult mConnectionResult;
private Button shareButton=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
shareButton=(Button)findViewById(R.id.share_button);
shareButton.setOnClickListener(this);
mPlusClient = new PlusClient.Builder(this, this, this)
.setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity")
.setScopes(Scopes.PLUS_LOGIN) // recommended login scope for social features
// .setScopes("profile") // alternative basic login scope
.build();
// Progress bar to be displayed if the connection failure is not resolved.
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
}
#Override
protected void onStart() {
super.onStart();
mPlusClient.connect();
}
#Override
protected void onStop() {
super.onStop();
mPlusClient.disconnect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mConnectionProgressDialog.isShowing()) {
// The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
if (result.hasResolution()) {
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
// Save the result and resolve the connection failure upon a user click.
mConnectionResult = result;
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
#Override
public void onConnected(Bundle connectionHint) {
String accountName = mPlusClient.getAccountName();
Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG).show();
}
#Override
public void onDisconnected() {
Log.d(TAG, "disconnected");
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.share_button:
Intent shareIntent = new PlusShare.Builder(this)
.setType("text/plain")
.setText("Welcome to the Google+ platform.")
.setContentUrl(Uri.parse("https://developers.google.com/+/"))
.getIntent();
startActivityForResult(shareIntent, 0);
break;
}
}
}
Thanks in advance
You don't need a client ID anywhere in the app - its inferred from the app packagename and the SHA1 of the signing key (which is why it asks for those in the API console). However, you don't need sign in or a key at all to do the kind of basic sharing you're doing. To test, you might want to remove all PlusClient/sign in related code until you're comfortable the PlusShare builder is creating the intent properly.
Could you make sure you're using the latest version of Google Play services (4.1) and see if you have any issues still? If so, could you check whether any more error details appear in logcat.