Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter and Firestore does not have user information in request

Using flutter, I have installed the firebase-auth and firestore packages and am able to both authenticate with firebase auth and make a call into firestore as long as I don't have any rules around the user.

I have a button that calls _handleEmailSignIn and I do get a valid user back (since they are in the Firebase Auth DB)

import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

final FirebaseAuth _auth = FirebaseAuth.instance;

void _handleEmailSignIn(String email, String password) async {
  try {
    FirebaseUser user = await _auth.signInWithEmailAndPassword(
        email: email, password: password);

    print("Email Signed in " + user.uid);  // THIS works
  } catch (err) {
    print("ERROR CAUGHT: " + err.toString());
  }
}

I then have another button that calls this function to attempt to add a record into the testing123 collection.

Future<Null> _helloWorld() async {
  try {
    await Firestore.instance
        .collection('testing123')
        .document()
        .setData(<String, String>{'message': 'Hello world!'});
    print('_initRecord2 DONE');
  } catch (err) {
    print("ERROR CAUGHT: " + err.toString());
  }
}

Now this works as long as I don't have any rules around checking the request user. This works...

service cloud.firestore {
  match /databases/{database}/documents {
    match /testing123auth/{doc} {
        allow read, create
    }
  }
}

This does not which gives PERMISSION_DENIED: Missing or insufficient permissions. when I want to make sure I have the authenticated user I did with _handleEmailSignIn.

service cloud.firestore {
  match /databases/{database}/documents {
    match /testing123auth/{doc} {
        allow read, create: if request.auth != null;
    }
  }
}

I suspect that the firestore request is not including the firebase user. Am I meant to configure firestore to include the user or is this supposed to be automatic as part of firebase?

like image 395
aqwert Avatar asked Mar 20 '18 04:03

aqwert


People also ask

How do I add user data to firestore Flutter?

just follow the steps: call userSetup Function from onpress while passing the display name data. the below code will create new document using the currect users uuid in firestore in user collection and save the data.

How do I display data from firestore in Flutter?

There should be array called contacts and inside that there should be 3 maps according to your data. Then create a list in your screen class. List contacts; Then create a function to retrieve data from firestore.

How do you read data from Firebase firestore in Flutter?

To use Flutter with Firebase, you will first need to set dependencies in the pubspec file. You will also have to import firestore , i.e., the database provided by Firebase for data handling. Now, import the Firebase dependencies into your Dart file. import 'package:cloud_firestore/cloud_firestore.


2 Answers

One thing to note that's not well documented is that firebase_core is the "Glue" that connects all the services together and when you're using Firebase Authentication and other Firebase services, you need to make sure you're getting instances from the same firebase core app configuration.

final FirebaseAuth _auth = FirebaseAuth.instance;

This way above should not be used if you're using multiple firebase services. Instead, you should always get FirebaseAuth from FirebaseAuth.fromApp(app) and use this same configuration to get all other Firebase services.

FirebaseApp app = await FirebaseApp.configure(
   name: 'MyProject',
   options: FirebaseOptions(
      googleAppID: Platform.isAndroid ? 'x:xxxxxxxxxxxx:android:xxxxxxxxx' : 'x:xxxxxxxxxxxxxx:ios:xxxxxxxxxxx',
      gcmSenderID: 'xxxxxxxxxxxxx',
      apiKey: 'xxxxxxxxxxxxxxxxxxxxxxx',
      projectID: 'project-id',
      bundleID: 'project-bundle',
   ),
 );
 FirebaseAuth _auth = FirebaseAuth.fromApp(app);
 Firestore _firestore = Firestore(app: app);
 FirebaseStorage _storage = FirebaseStorage(app: app, storageBucket: 'gs://myproject.appspot.com');

This insures that all services are using the same app configuration and Firestore will receive authentication data.

like image 152
ZeroNine Avatar answered Oct 05 '22 04:10

ZeroNine


There shouldn't be any special configuration needed for the firestore to do this.

This is all you should need. Modified from Basic Security Rules:

service cloud.firestore {
  match /databases/{database}/documents {
    match /testing123/{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

It seems they check if the uid is null rather than the auth itself. Try this out and see if it works. Also, it seemed that your code was inconsistent as the firestore rule had testing123auth and flutter had testing123. I'm not sure if that was intentional.

like image 20
Christopher Moore Avatar answered Oct 05 '22 04:10

Christopher Moore