Search code examples
fluttergoogle-cloud-firestorefirebase-authenticationgoogle-oauthfirebase-security

Some users get authenticated but not storing the data in firestore for my flutter app


I have an app where the users should be authenticated by google oauth first to enter the application. once authenticated the user data will be automatically created in the firestore. The problem is I can see in my firebase console in authentication tab that many new users getting authenticated but only some users data is being stored in firestore. I don't know why. Below is my firebase security rule.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null; 
    }
  }
}
class GoogleSignInProvider extends ChangeNotifier {
  final googleSignIn = GoogleSignIn();

  GoogleSignInAccount? _user;

  GoogleSignInAccount get user => _user!;

  Future googleLogin() async {
    try {
      final googleUser = await googleSignIn.signIn();
      if (googleUser == null) return;
      _user = googleUser;

      final googleAuth = await googleUser.authentication;

      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );

      await FirebaseAuth.instance.signInWithCredential(credential);

      notifyListeners();
    } catch (e) {
      if (kDebugMode) {
        print(e.toString());
      }
    }
  }

  Future logout() async {
    await googleSignIn.disconnect();
    FirebaseAuth.instance.signOut();
  }




}

Above is how i authenticate

Future<void> checkUser() async {

final user = FirebaseAuth.instance.currentUser!;
var collection = FirebaseFirestore.instance
    .collection('users')
    .where('gmail', isEqualTo: user.email);
var querySnapshots = await collection.get();

if (querySnapshots.docs.isEmpty) {

  final user = FirebaseAuth.instance.currentUser!;
  final createUser = FirebaseFirestore.instance.collection('users').doc();
  final firstToken = await FirebaseMessaging.instance.getToken();
  final userInformation = {
    'id': createUser.id,
    'name': user.displayName,
    'gmail': user.email,
    'token': firstToken
  };

  await createUser.set(userInformation);
} else {

   // if user already exists I will update here
}
}

Above is how I check the user if already exists or not and I will create the user in firestore. The checkUser() function is in a future builder

class Switcher extends StatelessWidget {
  const Switcher({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: CircularProgressIndicator(),
            );
          } else if (snapshot.hasData && snapshot.data != null) {

            return const HomeScreen();
          } else if (snapshot.hasError) {
            return const Center(
              child: Text('Something Went Wrong'),
            );
          } else {
            return const ContinuePage();
          }
        },
      ),
    );
  }
}

Above is how i check the auth state and navigate user to homescreen page where the checkUser function is there.

The code works fine for some users but for some users it is not working that's why I have no clue what is wrong.

I tried to look for answers but I didn't get any.


Solution

  • At last, I found out that there was no problem in the code. Those users who were not able to create the firestore document had one common thing, an email with a pattern like this [randomName].[randomNumber]@gmail.com. This is nothing but the firebase generated emails to test our app. Usually happens when you submit your app in play store.

    Check out this below question to know about this in detail

    Weird e-mails in my firebase project authenticated accounts