Developing an App which has Firebase as backend. Currently, was stuck while implementing Firebase App Invite . Just looking to send invites ( not currently trying to implement the clicking of the dynamic link by the installed new user) but the onActivityResult returns wrong result_code
Steps followed
Integrated FireBase SDK and authenticating successfully.
Enabled Firebase Dynamic link and referred in the app
Clicking on the invite button shows the inbuilt Firebase Activity with option to select users to invite and sent ( SMS or Email Invites )
the app returns back to the invite screen as expected.
Code Snippet
InviteActivity
btnInvite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new AppInviteInvitation.IntentBuilder(INVITATION_TITLE)
.setMessage(INVITATION_MESSAGE)
.setDeepLink(Uri.parse("https://ewyc6.app.goo.gl/eNh4"))
.setCallToActionText(INVITATION_CALL_TO_ACTION)
.build();
startActivityForResult(intent, REQUEST_INVITE);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode + "result_ok ="+RESULT_OK);
if (requestCode == REQUEST_INVITE) {
if (resultCode == RESULT_OK) {
// You successfully sent the invite,
// we can dismiss the button.
btnInvite.setVisibility(View.GONE);
String[] ids = AppInviteInvitation.getInvitationIds(resultCode, data);
StringBuilder sb = new StringBuilder();
sb.append("Sent ").append(Integer.toString(ids.length)).append(" invitations: ");
for (String id : ids) sb.append("[").append(id).append("]");
Toast.makeText(getApplicationContext(),"Invited!!!",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),"Sorry, unable to send invite.",Toast.LENGTH_SHORT).show();
}
}
}
//result_code is 3 and the RESULT_OK is -1 on debugging
New to Firebase stuff , would appreciate if point out what I m doing wrong.
After hours of struggle found the issue and fixed it, posting it here since it might be helpful to others too.
The initial hint was "Create invitations failed to error code: 3" Had a similar issue here in SO
Get suggested invitees failed due to error code: 3
But in my case the SHA1 certificate was already added, but the package name in Firebase turned out to be a case sensitive issue.
One more point worth taking note of, "api_key" in google-services.json downloaded from Firebase and Web Api Key are not related. I tried to copy and paste the web api key to the json file manually from dashboard to api_key under the misconception that might be the issue lead to the error.
Log onto Firebase Console: https://console.firebase.google.com
You will need to click on the "Add Fingerprint" button and then add on your SHA1 key. You do not need to redownload your google-services.json, you just need to add the SHA1 key.
Try sending an app invite from your app. It will now work.
Related
I have created an app but when I tried to test it on my minsdk which is API 21, google play services won't work.
The error I get is com.google.android.gms.common.api.ApiException: 4:.
I followed the setup guide, which means I have set my Google Play Services libs to version 11.8.0, it says I just have to use Android 4.2.2 which is API 17.
My compileSdkVersion is set to 27.
Is there something big I am misunderstanding here on how the compiling works? The app works fine on API 26 and 25, but fails when I try using it on API 24, with the same error as with API 21.
My build.gradle file looks like this.
https://gist.github.com/uruloke/f2f71dd6318d365cd53d74c274cd8523
When using the GoogleSignInClient.silentSignIn() from the addOnFailureListener, I get the following exception
com.google.android.gms.common.api.ApiException: 4:
at com.google.android.gms.common.internal.zzb.zzy(Unknown Source)
at com.google.android.gms.common.internal.zzbk.zzz(Unknown Source)
at com.google.android.gms.common.internal.zzbl.zzr(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.zzc(Unknown Source)
at com.google.android.gms.common.api.internal.BasePendingResult.setResult(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzg.zza(Unknown Source)
at com.google.android.gms.auth.api.signin.internal.zzt.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:565)
Also if I try to use the GoogleSignInClient.getSignInIntent(), no intent is shown when starting it, but in my onActivityResult, I get an result which is non-successful, but with an empty status message
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
Log.d(TAG, result.getStatus().toString());
if (result.isSuccess()) {
// The signed in account is stored in the result.
GoogleSignInAccount signedInAccount = result.getSignInAccount();
menuFragment.updateUi(signedInAccount);
} else {
String message = result.getStatus().getStatusMessage();
if (message == null || message.isEmpty()) {
message = "Failed to sign in to Play Games. Maybe try updating it?";
}
new AlertDialog.Builder(this).setMessage(message)
.setNeutralButton(android.R.string.ok, null).show();
}
}
}
public static final int SIGN_IN_REQUIRED
The client attempted to connect to the service but the user is not signed in. The client may choose to continue without using the API. Alternately, if hasResolution() returns true the client may call startResolutionForResult(Activity, int) to prompt the user to sign in. After the sign in activity returns with RESULT_OK further attempts should succeed.
Constant Value: 4
Source: CommonStatusCodes, emphasis mine
It looks like silentSignIn only works if you're signed in to Google on the device, to be precise:
We attempt to sign users in if:
There is one and only one matching account on the device that has previously signed in to your application, and
the user previously granted all of the scopes your app is requesting for this sign in.
Source: GoogleSignInApi#silentSignIn
I'm trying to retrieve the user PhoneNumber/email using Facebook Account kit.
I'm always getting an error as response:
200: Server generated an error: 145: API calls from the server require
an appsecret_proof argument
I already Disabled the option on Facebook Developer Dash Board.
Require app secret for server API calls
Here is my code:
public void onLoginPhone(final View view) {
final Intent intent = new Intent(getActivity(), AccountKitActivity.class);
AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder =
new AccountKitConfiguration.AccountKitConfigurationBuilder(
LoginType.PHONE,
AccountKitActivity.ResponseType.CODE); // or .ResponseType.TOKEN
// ... perform additional configuration ...
intent.putExtra(
AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
configurationBuilder.build());
startActivityForResult(intent, APP_REQUEST_CODE);
}
and this is onActivityResult:
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
#Override
public void onSuccess(final Account account) {
// Get Account Kit ID
String accountKitId = account.getId();
// Get phone number
PhoneNumber phoneNumber = account.getPhoneNumber();
String phoneNumberString = phoneNumber.toString();
// Get email
String email = account.getEmail();
}
#Override
public void onError(final AccountKitError error) {
// Handle Error
}
});
Simple solution to solve above problem, just follow following step.
Step 1 : Go to Facebook developer console
https://developers.facebook.com/
Step 2 : Select your application from the
https://developers.facebook.com/apps/
Step 3: After selecting your application Click on Account kit located at left side panel of console below the product Title.
Step 4 : After click on Account kit you see the Reuired App Secret switch button with yes/no option right side of it.
Step 5 : Turn Off (No) the Reuired App Secret from the there ( below the allow sms login )
Step 6 : Click on Save changes tab.
Step 7 : Run your application, you will got whatever you want.
If you have still any query ask me to any time. may be these help to you or other person.
I had the same problem. The three steps which solved my problem:
Turn off the option "App Require Secret"
Make sure the option "Enable Client Access Token Flow " has turned on, set
to "YES"
User this AccountKitActivity.ResponseType.TOKEN instead of AccountKitActivity.ResponseType.CODE
ResponseType.CODE will never return you the mobile number.
Hope it helps.
I am trying to use the Google Fit History API and I am running into an issue where after I prompt the user for their Google account using ConnectionResult.StartResolutionForResult, I am ALWAYS getting a return code of CANCELED even though the user selects the account via the dialog. I have followed the guides found here (https://developers.google.com/fit/android/get-api-key) to the letter, as far as I can tell. I have a project in my Developers console. I have enabled the Fitness API in the console. And I have generated a client id using the debug keystore on my development machine. Here are some screenshots from developers console:
I am programming in Xamarin.Android and followed the example here. (Note that I do have Xamarin.GooglePlayServices.Fitness package installed):
https://github.com/xamarin/monodroid-samples/tree/master/google-services/Fitness/BasicHistoryApi
Here are the key areas of the code:
mClient = new GoogleApiClient.Builder (this)
.AddApi (FitnessClass.HISTORY_API)
.AddScope (new Scope (Scopes.FitnessActivityReadWrite))
.AddConnectionCallbacks (clientConnectionCallback)
.AddOnConnectionFailedListener (result => {
Log.Info (TAG, "Connection failed. Cause: " + result);
if (!result.HasResolution) {
// Show the localized error dialog
GooglePlayServicesUtil.GetErrorDialog (result.ErrorCode, this, 0).Show ();
return;
}
// The failure has a resolution. Resolve it.
// Called typically when the app is not yet authorized, and an
// authorization dialog is displayed to the user.
if (!authInProgress) {
try {
Log.Info (TAG, "Attempting to resolve failed connection");
authInProgress = true;
result.StartResolutionForResult (this, REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.Error (TAG, "Exception while starting resolution activity", e);
}
}
}).Build ();
...
protected override void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
if (requestCode == REQUEST_OAUTH) {
authInProgress = false;
if (resultCode == Result.Ok) {
// Make sure the app is not already connected or attempting to connect
if (!mClient.IsConnecting && !mClient.IsConnected) {
mClient.Connect ();
}
}
}
}
The OnFailedConnectionListener is getting called with statusCode=SIGN_IN_REQUIRED, which then causes me to call StartResolutionForResult and pop up the dialog for the user to select their Google Account. As soon as the dialog is displayed I am getting the following error in my LogCat. Note that this is before they select the account.
02-26 15:56:36.459: E/MDM(17800): [63567] b.run: Couldn't connect to Google API client: ConnectionResult{statusCode=API_UNAVAILABLE, resolution=null, message=null}
Once the user selects the account, OnActivityResult gets called and resultCode is always "Canceled", which is supposed to indicate the user dismissed the dialog but that is certainly not what happened here. Any help? It smells like something is wrong in Developer Console but after going through the guide 100 times with the same results I'm starting to go crazy.
So my issue was that I was using the wrong debug.keystore. My Mac has both Android Studio and Xamarin Studio installed. I had incorrectly assumed that Xamarin was using "~/.android/debug.keystore" but it turns out that they put theirs in "~/.local/share/Xamarin/Mono for Android/debug.keystore" changing to using the SHA1 from this key fixed my issue. For my info on Xamarin keys:
https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/MD5_SHA1/#OSX
Use terminal to get the correct SHA for Xamarin using :
keytool -list -v -keystore ~/.local/share/Xamarin/Mono\ for\ Android/debug.keystore -alias androiddebugkey -storepass android -keypass android
As pointed out by #thedigitalsean there are different keystores for Android Studio & Xamarin (Visual Studio).
Android Studio Keystore is in location .android
Xamarin keystore is in location .local/share/Xamarin/Mono for Android
Microsoft Reference : https://learn.microsoft.com/en-us/xamarin/android/deploy-test/signing/keystore-signature?tabs=vsmac
I'm working on a project where I need to upload a file to google Drive, to download it with another app.
I wanted to use the Drive Id, which I get by creating a file, to find it later, but this seems not to work.
I used an example from Google to get the ID:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_CREATOR:
if (resultCode == RESULT_OK) {
driveId = data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
showMessage("File created with ID: " + driveId);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
This seemed to work so far, I am getting the Drive ID.
After this, I wanted to test it by using the Example "Files: get" from the Google Developers-page, where I got the following error:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "File not found: CAESABiCASCQ1OnN-VMoAA==",
"locationType": "other",
"location": "file"
}
],
"code": 404,
"message": "File not found: CAESABiCASCQ1OnN-VMoAA=="
}
}
It seems like this ID is not the id to find files.
There must be something I missed but i don't know what.
I am new to programming, especially to Google and Android and I would be very happy if any one can help me through their answers.
Thanks.
There are two problems with your approach.
1/ You can not use the DriveId for anything outside your Android App instance, you have to go for the ResourceId (see SO 32210970)
2/ The DriveId you're showing above is the 'preliminary' DriveId that is returned by GooPlaySvcs before the object is committed (uploaded) (see SO 22874657). Also, you can't get a valid ResourceId until it the object is committed.
See also SO 33355665, SO 29030110
If you intent to take the ResourceId 'outside' (to a different app), you'll be OK. If you decide to use this ResourceId in the same Android app, mixing the two Apis (GDAA and REST), you will potentially introduce latency issues, since GDAA is a 'buffering' layer between your app and the REST api (you've already run into one with your 'invalid' DriveId).
Good Luck
I'm following the documentation of google plus list and I am using this code:
Plus.Activities.List listActivities = plus.activities().list("me", "public");
listActivities.setMaxResults(5L);
// Execute the request for the first page
ActivityFeed activityFeed = listActivities.execute();
// Unwrap the request and extract the pieces we want
List<Activity> activities = activityFeed.getItems();
// Loop through until we arrive at an empty page
while (activities != null) {
for (Activity activity : activities) {
System.out.println("ID " + activity.getId() + " Content: " +
activity.getObject().getContent());
}
// We will know we are on the last page when the next page token is null.
// If this is the case, break.
if (activityFeed.getNextPageToken() == null) {
break;
}
// Prepare to request the next page of activities
listActivities.setPageToken(activityFeed.getNextPageToken());
// Execute and process the next page request
activityFeed = listActivities.execute();
activities = activityFeed.getItems();
This does not work because I have to create a client object. I tried more example but I do not understand how to do. Now:
How do I create a client object?
Where do I insert this client object?
I've seen a lot of answers but none work. You can Help me.
The comment that proceeded that code sample asked you to take a look at the Google+ Java quickstart, see the source file in question for how to set up your credentials and Plus client. You'll also need to authorize your request, that sample project shows how to use Google+ Sign-In to authorize the user to get an access token. You must have an authorized user to search with "me".
This sample is Java code using the Google Java API client library, the Android SDK doesn't include the client library by default, so you'd need to import that into your project.
I think you should take a look at this project : google API calendar
It works exactly like that with the G+ API.