简体   繁体   中英

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

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?

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();
    }
  }

}

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM