io.realm.PermissionManager is not recognized - android

I am developing a shared shopping list application where an user can share his/her list with the family members. I am using Realm Object Server as a database to store all the lists and users. To grant the read permission to the other users (aka family members), I decided to use Full-Sync permissons and I found the following code snippet in appropriate Realm docs. But the problem is io.realm.PermissionManager class is not recognized in my project.
PermissionManager pm = user.getPermissionManager();
// Create request
UserCondition condition = UserCondition.username(username);
AccessLevel accessLevel = AccessLevel.WRITE;
PermissionRequest request = new PermissionRequest(condition, url, accessLevel);
pm.applyPermissions(request, new PermissionManager.ApplyPermissionsCallback() {
#Override
public void onSucesss() {
// Permissions where succesfully changed
}
#Override
public void onError(ObjectServerError error) {
// Something went wrong
}
});
To install Realm in my project I did the following step:
adding classpath "io.realm:realm-gradle-plugin:6.0.1" to project level build.gradle file
applying plugin: 'realm-android' to application level build.gradle file
Do I miss something to insert io.realm.PermissionManager to my project?

In current realm api class PermissionsManager does not exist. I checked it here:
https://realm.io/docs/java/6.0.1/api/overview-summary.html
Maybe you're using some example with old api?
More information you cand find in changelog of realm:
https://github.com/realm/realm-java/blob/master/CHANGELOG.md
In version 6.0.0 there was a breaking change with PermissionManager.

Related

google_sign_in Flutter plugin always returns null serverAccessCode

I have the current workflow for my authentication
User signs in via google OAuth2
User is then given a server_auth_code which they send to my backend authentication
The auth code is validated on the back end and users is sent a JWT
I had this all working in raw Java with the Android SDK, but Flutter seemed a lot nicer. But now when using the google_sign_in plugin on android, I am unable to retrieve the serverAuthCore anymore, this plugin just wants to return null the entire time.
I Am using the client ID that's specified for Android, however, I tested the WebApplication that's auto-generated by google too but that's the same issue (Null serverAutHCode)
This is the code that I am currently using:
/// Provides the `GoogleSignIn` class
import 'package:google_sign_in/google_sign_in.dart';
class GoogleLoginPage extends StatefulWidget {
final String name = "Logging in with google.";
late GoogleSignIn _googleSignIn;
GoogleLoginPage() : super() {
_googleSignIn = GoogleSignIn(
scopes: ['https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'],
serverClientId: "XX-XXX.apps.googleusercontent.com"
);
}
Future<void> fetchAuthToken() async {
try {
var response = await _googleSignIn.signIn();
log(response?.serverAuthCode ?? "No server auth code");
_googleSignIn.signOut();
} catch (error) {
print("ERR");
print(error);
}
}
#override
State<GoogleLoginPage> createState() => GoogleLoginState();
}
The output of this code is: [log] No server auth code
The question:
Am I doing something wrong? As mentioned this works 100% on my java project using the google play services SDK so I know it's nothing to do with my google console configurations.
Okay so I figured out the issues:
It appears that by default the google login plugin for flutter comes on an older version (If I remember correctly it was 20.0.5)
I Simply changed the version to the latest version:
'com.google.android.gms:play-services-auth:20.2.0'
You can do this by editing the project's build.gradle (In IntelliJ you open build.gradle and click "Open for editing in the android studio" in the top right, from there you need to find the gradle file for google_sign_in, and change the import there, remember to click sync in the top right of android studio before you close out of it)
And I began to receive my serverAuthCode as normal, cheers!

Firebase Functions AppCheck keeps failing my device

I have been trying to integrate AppCheck with my Android app, but I can't seem to make a valid request.
As for test purposes, I have been using the following code:
Android Code
class Application : MultiDexApplication() {
override fun onCreate() {
FirebaseApp.initializeApp(this)
val appCheck = FirebaseAppCheck.getInstance()
if (BuildConfig.DEBUG) appCheck.installAppCheckProviderFactory(DebugAppCheckProviderFactory.getInstance(), true)
else appCheck.installAppCheckProviderFactory(SafetyNetAppCheckProviderFactory.getInstance(), true)
super.onCreate()
}
}
class TestActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
val data = "This is a test!"
Firebase.functions.getHttpsCallable("test").call(data).addOnCompleteListener {
if (it.isSuccessful) {
val result = it.result.data
print(result)
}
else {
val exception = it.exception
print(exception)
}
}
}
}
Function Code
const functions = require("firebase-functions")
exports.test = functions.https.onCall((data, context) => {
if (context.app == undefined) {
functions.logger.error("Test - Failed validating device integrity!")
throw new functions.https.HttpsError("failed-precondition", "The function must be called from an App Check verified app")
}
return data
})
I have added the DebugAppCheckProviderFactory token to the Firebase console, but no matter what I do, if it is an emulator or physical device, when I call the function, the failed-precondition exception is always thrown.
Checking the function logs, I can see that the app is missing:
I have already read the documentation multiple times and I can't seem to be missing any step. Am I missing something or is there anything I can do to find the root cause for this?
Thank you for your time!
EDIT:
As for Martin suggestion, I created a new OnRequest function and added the X-Firebase-AppCheck header. I received the token correctly and was able to validate it successfully with:
firebaseAdmin.appCheck().verifyToken(appCheckToken)
So, my guess is that Android is not adding the X-Firebase-AppCheck automatically to the OnCall function like it should.
I ran the code and made some breakpoints through the code and noticed the following. The call method from Firebase is adding the Firebase-Instance-ID-Token but I can't seem to find the X-Firebase-AppCheck header anywhere. Maybe I am not supposed to see this value, or maybe I just can't find where it is being added. Or maybe it is not added at all, thus I can't validate my context.app at all.
It may be required to obtain an AppCheckToken:
FirebaseAppCheck
.getInstance()
.getAppCheckToken(false)
.addOnSuccessListener(new OnSuccessListener<AppCheckToken>() {
#Override
public void onSuccess(#NonNull AppCheckToken tokenResponse) {
String appCheckToken = tokenResponse.getToken();
...
}
});
Which has to be passed along, with the HTTP request (the example shows Retrofit, which could also be used instead of HttpsCallable:
#GET("yourExampleEndpoint")
Call<List<String>> exampleData(
#Header("X-Firebase-AppCheck") String appCheckToken,
...
);
Where FirebaseFunctions.getInstance().getHttpsCallable().call() doesn't tell how or if one has to explicitly set that X-Firebase-AppCheck header. Cloud Functions should usually receive an X-Firebase-AppCheck header - with the previously retrieved AppCheck token:
const appCheckToken = req.header('X-Firebase-AppCheck');
if (!appCheckToken) {
res.status(401);
return next('Unauthorized');
}
try {
const appCheckClaims = await firebaseAdmin.appCheck().verifyToken(appCheckToken);
// If verifyToken() succeeds, continue with the next middleware function in the stack.
return next();
} catch (err) {
res.status(401);
return next('Unauthorized');
}
One can also issue own tokens ...and checking for context-app is also valid.
Update: The Protocol specification for https.onCall reads:
Optional: X-Firebase-AppCheck: <token>
The Firebase App Check token provided by the client app making the request. The backend automatically verifies this token and decodes it, injecting the appId in the handler's context. If the token cannot be verified, the request is rejected.Available for SDK >=3.14.0
To install the minimum required NodeJS dependencies:
npm install firebase-functions#">=3.14.0"
npm install firebase-admin#">=9.8.0"
And last, but not least ...there's even a debug helper for that:
dependencies {
debugImplementation "com.google.firebase:firebase-appcheck-debug:16.0.0-beta02"
}
After testing everything with no success, in a desperate move, I tried to look to unrelated files and found the solution.
In my build.gradle I was importing all the Firebase dependencies with the bom:
implementation platform("com.google.firebase:firebase-bom:27.0.0")
implementation "com.google.firebase:firebase-crashlytics-ktx"
implementation "com.google.firebase:firebase-analytics-ktx"
implementation "com.google.firebase:firebase-firestore-ktx"
implementation "com.google.firebase:firebase-functions-ktx"
implementation "com.google.firebase:firebase-auth-ktx"
So I thought: "Can the firebase-bom be importing an outdated functions-ktx dependency?"
And guess what? As soon as I imported the dependencies without the bom, I started to see the X-Firebase-AppCheck being added and the context.app being valid.
I ended up with the following build.gralde:
implementation "com.google.firebase:firebase-crashlytics-ktx:18.2.1"
implementation "com.google.firebase:firebase-analytics-ktx:19.0.0"
implementation "com.google.firebase:firebase-firestore-ktx:23.0.3"
implementation "com.google.firebase:firebase-functions-ktx:20.0.0"
implementation "com.google.firebase:firebase-auth-ktx:21.0.1"
After a little more investigation, I found out that I was using an outdated firebase-bom version. Android Studio used to let me know if there was a new version for the dependencies, but it did not notice me for the firebase-bom. Turns out, that I just need to update my firebase-bom dependency.
TL;DR
Check your Android Firebase libraries version!

Android + Google Fit Data Upload : error 5002 - DataType's name does not match package name

In an app we upload user activity data to Google Fit like this :
Fitness.getSessionsClient(context, GoogleSignIn.getLastSignedInAccount(context))
.insertSession(((SessionInsertRequest) object))
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// At this point, the session has been inserted and can be read.
if (BuildConfig.DEBUG) {
Log.i(TAG, "Session insert was successful!");
}
//more success handling
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (BuildConfig.DEBUG) {
Log.w(TAG, "There was a problem inserting the session: " + e.toString()+ "\n"+ e.getLocalizedMessage());
}
//more error handling
}
}
});
This was working fine until approx sep 4 2019.
Then Google seemed to have changed something resulting in the following warning when creating the SessionInsertRequest
App com.foo.bar does not have access to data types in request
and in onFailureListener(...) we get the following message:
There was a problem inserting the session: com.google.android.gms.common.api.ApiException: 5002: DataType's name does not match package name.
DataTypes were not changed. They are requested when the user is asked to give permission to upload :
private FitnessOptions getFitnessSignInOptions(OAuthType type) {
switch (type) {
case Activity:
return FitnessOptions.builder()
.addDataType(DataType.TYPE_LOCATION_SAMPLE, FitnessOptions.ACCESS_WRITE)
.addDataType(DataType.TYPE_CALORIES_EXPENDED, FitnessOptions.ACCESS_WRITE)
.build();
}
}
and created in a DataSource like :
DataSource locationDataSource = new DataSource.Builder()
.setAppPackageName(packageName)
.setDataType(DataType.TYPE_LOCATION_SAMPLE)
.setName(uniqueIdentifier + "-locations")
.setType(DataSource.TYPE_RAW)
.build();
similar as the Google sample shows.
It does not matter if we omit setting the name of the dataSource or using setName(packageName). Also using setStreamName(packageName) instead does not resolve the issue.
Anybody else having this or a similar issue ?
Thank you
Robert
I wonder if the issue is related to the use of GoogleSignIn.getLastSignedInAccount. Apparently in the new version of the library this is not liked. Using GoogleSignIn.getAccountForExtension should do the trick. It worked for my issue with locations
I believe that you may have provided an invalid google-services.json file or at least one that is not compatible with the one used when you acquired permission from the user to use Google Fit.
I had the same issue: when I uploaded the new version of my app on top of the one downloaded from Google Play, it gave this error. It did not happen if instead I installed the new version of the app from scratch.
Regenerating the google-services.json file on Firebase and giving it to the new version of the app solved the issue. Now I can upload the app on top of the existing one and I do not get this error any more.
Note however that before I did not have Firebase enabled so it is possible that Google does not allow any more using google-services.json that is not generated via Firebase

Firebase dynamic link request contains an invalid argument

Am trying to build a dynamic url, using Firebase dynamic links but i get a exception.
private void sendNativeInvites(){
String email = UserUtils.getCurrentUser(this).getEmail();
String link = "https://play.google.com/store/apps/details?id=com.mindedges.beephourly?invitedby=" + email;
FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse(link))
.setDomainUriPrefix("https://c6yge.app.goo.gl")
.setAndroidParameters(
new DynamicLink.AndroidParameters.Builder("com.example.android")
.setMinimumVersion(125)
.build())
.buildShortDynamicLink()
.addOnSuccessListener(new OnSuccessListener<ShortDynamicLink>() {
#Override
public void onSuccess(ShortDynamicLink shortDynamicLink) {
Log.e(TAG, "Successfully built build dynamic link");
Uri invitationUrl = shortDynamicLink.getShortLink();
doSendInvite(invitationUrl);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "failed to build dynamic link", e);
}
});
}
failed to build dynamic link
com.google.android.gms.common.api.ApiException: 400: Request contains an invalid argument.
at com.google.android.gms.common.api.internal.TaskUtil.setResultOrApiException(Unknown Source:12)
at com.google.firebase.dynamiclinks.internal.zzi.zza(Unknown Source:4)
at com.google.firebase.dynamiclinks.internal.zzn.dispatchTransaction(Unknown Source:10)
at com.google.android.gms.internal.firebase_dynamic_links.zzb.onTransact(Unknown Source:12)
at android.os.Binder.execTransact(Binder.java:697)
Am not getting what wrong param am passing. I own the domain "https://c6yge.app.goo.gl" as per firebase console.
I can see a minor error in your code. That have been caused by mistakenly copying some codes from the documentation without editing them.
Here is the lines that has caused your problems:
.setAndroidParameters(
new DynamicLink.AndroidParameters.Builder("com.example.android")
.setMinimumVersion(125)
.build())
Instead of "com.example.android" you were supposed to replace that with your own package name which I think it is "com.mindedges.beephourly". So in the documentation they wrote that just like an example but you were expected to change it to your own package name.
Also in the same code above instead of (125) you are supposed to change that to your own version code. In android there are version codes for Apps and when you update an app you will have to change version code (integer) and version name (String) so you may have a number of App versions but in there you were supposed to pass the minimum the lowest version code that can open that dynamic link. I am forced not to believe you have ever made 125 updates in your app in Playstore. So if you want all your apps old and new version to open you could replace (125) with (1). You can find the current version code in your build.gradle files. In your project.
Let me know if you still face some difficulties.
Can you double check if you got the correct domain? Based on your code, it looks like everything works fine. However, the issue seems to be with your domain.
Checking the link as https://c6yge.app.goo.gl/?link=https://google.com, you should be redirected to https://google.com but it didn't. Instead, it just shows Dynamic Link not Found. So I'm thinking it's not properly configured.
Here's a sample working link: https://ratbu.page.link/?link=https://google.com.

Error : "Forbidden" when doing GeocodeRequest in Here-API for android

When doing a Geocoderequest in the Here API for Android I get the result FORBIDDEN for any search string.
Here is a snippet of the code (Kotlin) :
class GeoListner : ResultListener <MutableList<Location>>
{
override fun onCompleted(p0: MutableList<Location>?, p1: ErrorCode?) {
Log.d(this.javaClass.toString(),"Result code of search is ${p1?.name}")
}
}
fab_search.setOnClickListener { View ->
var currentPos = GeoCoordinate(49.2849,-123.1252)
val listner : ResultListener<MutableList<Location>> = GeoListner()
val request = GeocodeRequest("Granville").setSearchArea(currentPos,5000)
if (request.execute(listner) != ErrorCode.NONE)
{
}
}
This search area and string is picked from the HERE-API documentation for Here. Also i notice that the GeocodeRequest is deprecated, but the result for GeocodeRequest2 is the same error.
Anyone ?
Regards
Trond
Summary: Please ensure that you set the APP_ID and APP_CODE in the manifest file correctly.
For the background: Developers using HERE SDK with their app are required to register for a set of HERE credentials and to specify these credentials (App_Id and App_Code) in their app's Android manifest XML file. Failure to do so results in blocked access to certain features and degradation in the quality of other services.
To obtain these credentials visit the developer portal at https://developer.here.com/plans and register for a license. Once your project is created, you can generate these credentials on your Project Details page. If you already have a plan, you can also retrieve these credentials from your Project Details page.
Note: Credentials are unique to your account and your application's package namespace. Avoid reusing credentials across multiple applications.

Categories

Resources