Firestore rules aren't working for users following official documentation - google-cloud-firestore

So I am running my Flutter app locally with emulators. The firestore rules are copied from the docs:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}
After I signup the user successfully I try to create his doc like this:
UserCredential userCredential = await auth
.createUserWithEmailAndPassword(email: data.name!, password: data.password!);
await auth.currentUser!.sendEmailVerification();
DocumentReference ref = FirebaseFirestore.instance.collection("users").doc(FirebaseAuth.instance.currentUser!.uid);
await ref.set({"isOwner":false},SetOptions(merge: true));
This results in the error:
W/Firestore(17604): (24.4.0) [Firestore]: Write failed at
users/JknXHMkWb0jL4ohiW18K9h6NLyyB: Status{code=PERMISSION_DENIED,
description=Missing or insufficient permissions., cause=null}
Does it need time to get the uid? I can't think of anything else

if (Foundation.kDebugMode) {
FirebaseFirestore.instance.clearPersistence();
FirebaseFirestore.instance.useFirestoreEmulator("10.0.2.2", 8080);
}
Found this on some google group. Moving the clearPersistence line below the firestore emulator made it work. This is really non-standard behavior.

Look out as well into the debugging output of your app : the Firebase Firestore SDK outputs a debug token for you to whitelist your test device on Firebase > AppCheck > Apps.
From there, look for the 3-dots menu of the platform you're debugging onto, click it, and select "Manage debug tokens" : add the token here.
From my observations, this debug token doesn't live forever. If experience again permissions issues, try re-adding the token which you get in the debug output.

Related

Firebase: What signatures should be present in Settings?

In Firebase, whenever I try to write to Firestore I'm getting permission errors in flutter. So I wanted to ask what signatures are you supposed to put in the settings? I'm currently using the services Firestore, Auth, and AppCheck.
I have 6 signatures in my settings:
SHA-1, SHA-256: debug.keystore
SHA-1, SHA-256: upload-keystore (is this needed?)
SHA-1, SHA-256: App signing key certificate from google console
The reason why I think it has something to do with the signatures is because I'm able to write to Firestore when I'm using AndroidProvider.debug in AppCheck. But when I make my release version using AndroidProvider.playIntegrity Firestore denies me.
Error:
E/flutter (25396): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.
Firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if isDev();
}
function isAuth() {
return request.auth != null;
}
function isDev() {
let datalist = ['myemail#foo.com'];
return isAuth() && request.auth.token.email in datalist;
}
}
}
I'm using IntelliJ.
You should use the SHA-256 certificate fingerprint that you can find in App integrity > App signing key certificate on the Google Play Console.
I stumbled upon the same issue today, and this is my current working setup. Hope this helps!
Okay long story short, I found out the phone I was testing API 28 on had been previously rooted. The original ROM had eventually been reinstalled but I guess it still qualifies as being rooted according to AppCheck.

how to block access for non-authorized users to get pictures link from firestore storage?

I have an image link that I want to protect for only authorize users but the issue whenever I try to get the link I can see the picture, even if I specify the rule for it ?
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /profiles/{userId}/{image} {
// Read from storage !!
allow get : if request.auth != null // Authorized users only
}
}
}
If you're referring to download URLs, those are not at all controlled by security rules or any form of authentication. Anyone who has the link can view the content. That behavior can't be changed.

Permission Denied Error in Android Emulator when Enforcing App Check for Flutter App

After spending hours for getting App Check working on the physical devices (iOS and Android) of my Flutter app i also tried the provided documentation steps in order to get it working for Android emulator as well.
Whatever i try i always get the following error for all my listening streams that are invoked against the Firestore database when App Check is enforced:
W/Firestore( 5612): (24.1.2) [Firestore]: Listen for Query(target=Query(Contract where isArchive==false and contractorId==myContractorId order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
I've added the depencency in app/build.gradle:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-appcheck-debug:16.0.0'
}
and have overridden onCreate in MainActivity.kt:
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
if (BuildConfig.DEBUG) {
//Log.d("MainActivity", "debug mode entered")
FirebaseApp.initializeApp( /*context=*/this)
val firebaseAppCheck: FirebaseAppCheck = FirebaseAppCheck.getInstance()
firebaseAppCheck.installAppCheckProviderFactory(DebugAppCheckProviderFactory.getInstance())
} else {
//Log.d("MainActivity", "else mode entered")
}
super.onCreate(savedInstanceState)
}
}
The resulting debug token was added successfully to the list of debug tokens in Firebase console.
All Firestore collection rules look like the following example rule:
match /Contractor/{contractor} {
allow read, write: if request.auth.uid != null;
}
Activating App Check in the Flutter main function looks like this:
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await FirebaseAppCheck.instance.activate();
Without enforced App Check i don't have any problems running the Flutter app on my Android emulator.
All Firebase plugins are the most recent ones.
What else can i try or change in order to get this working?
If it doesn't work also on Android emulators we will give up using App Check.
Have you added this in cloud function:
if (context.app == undefined && !process.env.FUNCTIONS_EMULATOR) {
throw new functions.https.HttpsError(
"failed-precondition",
"The function must be called from an App-Check verified app.");
}
You need to add this code:
!process.env.FUNCTIONS_EMULATOR

Flutter: Authentication with Azure AD B2C returns result but with empty accesstoken

I try to build a Flutter app with Azure B2C authentication. To achive this I use the Flutter App Auth Plugin. At first sight everything seems to work as expected, but when I looked at the result the accesstoken is null. What am I missing? Obviously, I can get a connection to Azure and after entering the credentials a result is send back to my app. But why without token?
Debug session of the result:
Debug session of the result
My configuration:
configuration
I call the method like this:
Future<void> _login() async{
AuthorizationTokenResponse result;
try{
result = await _appauth.authorizeAndExchangeCode(
AuthorizationTokenRequest(_clientId, _redirectUrl,
discoveryUrl: _discoveryUrl,
scopes: _scopes),
);
}
catch(e){
print(e.toString());
}
if (result != null) {
_processAuthTokenResponse(result);
}
}
Does anybody know what I forgot?
Thanks!
You aren’t giving a scope to a resource so you don’t get an access token.
https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens

Flutter - How to link social account using Firebase facebook and google plugin

I have a flutter app and would like the user to authenticate both with FB and Google. I do not want multiple accounts, just a single account that links both.
I am using :
firebase_auth 0.15.1
google_sign_in 4.0.14
facebook_plugin 3.0.0
I am not able to get the email address of the user when the user's account already exist with a different provider. The email is needed in order to get the list of providers for that user using the API call "fetchSignInMethodsForEmail"
Here is an example:
1: User login with Google credentials. The account is created in firebase and google is linked.
2: The user now logoff
3: The user now tries to login with FB with the same email.
-- User get the following error
code:"ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL"
details: null
message: "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address., **null**))
As you can see the email is null. I need the email in order to get a list of providers. Then I can redirect the user to correct provider
here is a snippet of my code
Future<FirebaseUser> signInWithFacebook({bool isIos}) async {
AuthCredential credential;
try {
final FacebookLoginResult result = await facebookLogin.logIn(['email']);
if (result.accessToken != null) {
credential = FacebookAuthProvider.getCredential(
accessToken: result.accessToken.token
);
AuthResult authResult = await _firebaseAuth.signInWithCredential(
credential,
);
firebaseUser = authResult.user;
return firebaseUser;
} catch (e) {
throw Exception(e);
}
return null;
}
Thanks for your help