Home > database >  Should I pass the google sign-in variables to other class?
Should I pass the google sign-in variables to other class?

Time:08-16

I made a log-in page and made a button for google log-in like this :

Future<String> login_google() async{
  FirebaseAuth auth = FirebaseAuth.instance;
  GoogleSignIn googleSignIn = GoogleSignIn();
  GoogleSignInAccount? account = await googleSignIn.signIn();
  GoogleSignInAuthentication authentication = await account!.authentication;
  AuthCredential credential = GoogleAuthProvider.credential(
      idToken: authentication.idToken,
      accessToken: authentication.accessToken);

  final authResult = await auth.signInWithCredential(credential);
  final user = authResult.user;

  print (user?.uid);
  print (user?.email);
  print('google log-in completed');
  return Future.value(user?.uid);
}


...


class _login_pageState extends State<login_page> {
  @override
  Widget build(BuildContext context) {
//    String uid_r = await login_google();
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.white,
          toolbarHeight: 1.0,
        ),
        body:Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Image( image: AssetImage('asset/logo.png'),),
            ElevatedButton(onPressed: (){
              login_kakao();
              Navigator.of(context).push(MaterialPageRoute(builder: (context) =>main_bone(uid:'')));
            }, child: Text('Kakao Log-In')),
            ElevatedButton(onPressed: (){
//              login_kakao();
            final uid = login_google().then(
                (value){
                  Navigator.of(context).push(MaterialPageRoute(builder: (context) =>main_bone(uid: value))); => The button for LOG-IN .
                }
            );
            }, child: Text('Google Log-In'))

          ],
        ),

    );
  }
}

Here I succeeded in log-in and passed only uid thinking that only uid is required. And My firestore rules for accessing is following :

 match /post/{document=**} 
    {
      allow read;
      allow write:if
      auth.uid != null; 
    }

On the next page, None of the data in collection(post) were shown, which means the log in has disabled on the next class .

Should I pass the whole variables for authentication to next class, for example, auth, credential ?

CodePudding user response:

its called inherited widget, there is a lot method to make your entire app authenticated, not just one class. make a stream builder, listen firebase_auth.authStateChanges()

or you can use a package ( state management ) : like flutter_bloc or

i prefer goRouter

check this video, its chris itself explain how to use it, its even better; work at flutter web too

take look at mine for your reference :

import 'dart:ui';
import 'package:cms_prototype/auth/auth.dart';
import 'package:cms_prototype/home/home.dart';
import 'package:cms_prototype/login/login.dart';
import 'package:cms_prototype/theme.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';


Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
      options: const FirebaseOptions(
          apiKey: "********",
          authDomain: "",
          appId: "",
          measurementId: "",
          storageBucket: "**.com",
          messagingSenderId: "**",
          projectId: "**"));

  final auth = AuthRepo();
  await auth.user.first;

  final router = GoRouter(

      urlPathStrategy: UrlPathStrategy.path,
      redirect: (GoRouterState state){
        if(auth.currentUser.isEmpty && state.location != '/login'){
          return '/login';
        }
        if(auth.currentUser.isNotEmpty && state.location == '/login'){
          return '/';
        }
        return null;
      },
      refreshListenable: GoRouterRefreshStream(auth.user),
      routes: [
        GoRoute(
            name: 'home',
            path: '/',
            pageBuilder: (context, state) => MaterialPage(
                key: state.pageKey,
                child: const HomePage())),
        GoRoute(
            name: 'login',
            path: '/login',
            pageBuilder: (context, state) => MaterialPage(
                key: state.pageKey,
                child: LoginPage(authRepo: auth,))),
      ],
      errorPageBuilder: (context, state) => const MaterialPage(
          child: Scaffold(
            body: Center(
              child: Text("404 Error"),
            ),
          )));

  runApp(MyApp(router: router,authRepo: auth,));
}

class MyApp extends StatelessWidget {
  final GoRouter router;
  final AuthRepo authRepo;
  const MyApp({Key? key, required this.router, required this.authRepo}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {


    return MaterialApp.router(
      routeInformationProvider: router.routeInformationProvider,
      routeInformationParser: router.routeInformationParser,
      routerDelegate: router.routerDelegate,
      debugShowCheckedModeBanner: false,
      scrollBehavior: const MaterialScrollBehavior().copyWith(
        dragDevices: {
          PointerDeviceKind.mouse,
          PointerDeviceKind.touch,
          PointerDeviceKind.stylus,
          PointerDeviceKind.unknown
        },
      ),
      title: 'CMS Prototype',
      theme: appTheme,
    );
  }
}

auth repo class : ---->

class AuthRepo {

  final AuthCache _cache;
  final firebase_auth.FirebaseAuth _firebaseAuth;
  final GoogleSignIn _googleSignIn;

  AuthRepo({AuthCache? cache, firebase_auth.FirebaseAuth? firebaseAuth, GoogleSignIn? googleSignIn})
  : _cache = cache?? AuthCache(),
  _firebaseAuth = firebaseAuth ?? firebase_auth.FirebaseAuth.instance,
  _googleSignIn = googleSignIn ?? GoogleSignIn.standard();

  Stream<User> get user {
    return _firebaseAuth.authStateChanges().map((fUser){
     final user = fUser == null ? User.empty : fUser.toUser;
     _cache.write(key: user.id, value: user);
     return user;
    });
  }

  User get currentUser {
    final key = _firebaseAuth.currentUser != null? _firebaseAuth.currentUser!.uid : '';
    return _cache.read(key: key) ?? User.empty;
  }

  Future<void> signUp({required String email, required String password}) async {
    try {
      await _firebaseAuth.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );
    } on firebase_auth.FirebaseAuthException catch (e) {
      throw SignUpWithEmailAndPasswordFailure.fromCode(e.code);
    } catch (_) {
      throw const SignUpWithEmailAndPasswordFailure();
    }
  }

  //login with google (GOOGLE SIGN IN)
  Future<void> loginWithGoogle() async {
    try {
      late final firebase_auth.AuthCredential credential;
      if(kIsWeb){
        final googleProvider = firebase_auth.GoogleAuthProvider();
        final userCredential = await _firebaseAuth.signInWithPopup(googleProvider);
        credential = userCredential.credential!;

      }else{
        final googleUser = await _googleSignIn.signIn();
        final googleAuth = await googleUser!.authentication;
        credential = firebase_auth.GoogleAuthProvider.credential(
          accessToken: googleAuth.accessToken,
          idToken: googleAuth.idToken
        );
      }

      await _firebaseAuth.signInWithCredential(credential);
    }
    on firebase_auth.FirebaseAuthException catch (e){
      throw LogInWithGoogleFailure.fromCode(e.code);
    }
    catch (e){
      throw const LogInWithGoogleFailure();
    }
  }

  //email dan password

  Future<LogInWithEmailAndPasswordFailure?> loginWithEmailAndPassword ({required String email, required String password}) async{
    try{
      await _firebaseAuth.signInWithEmailAndPassword(
          email: email,
          password: password
      );
    }
    on firebase_auth.FirebaseAuthException catch (e){
      //return e.code;
      return LogInWithEmailAndPasswordFailure.fromCode(e.code);
    }
    catch (_){

      //return 'masalah jaringan terdeteksi';
      return const LogInWithEmailAndPasswordFailure();
    }
    return null;
  }

  Future<void> logOut() async {
    try {
      await Future.wait([
        _firebaseAuth.signOut(),
        _googleSignIn.signOut(),
      ]);
    } catch (_) {
      throw LogOutFailure();
    }
  }

}

CodePudding user response:

You should be able to access all the data for the current user using FirebaseAuth.instance.currentUser. Use that to access the current user and pass any data to backend using that user's credentials and token.

final user = FirebaseAuth.instance.currentUser;
  • Related