При входе в систему может отображаться имя и т. Д., Но в случае выхода из системы отображается только «ноль». Нет сообщения типа «Не вошли» - PullRequest
0 голосов
/ 07 мая 2019

Чтобы понять, как войти в Google, я использую простой пример для входа и выхода. Идея состоит в том, чтобы отобразить имя пользователя, если оно выполнено, или «Не вошли», если оно выполнено. Если я вхожу в систему, имя пользователя отображается правильно. Если я выйду из системы, вместо сообщения «Не авторизовано» будет отображаться «null». Код:

String displayName =
    _profile != null ? '${_profile['displayName'].toString()}' : 'Not 
signed in';

не присваивает «Не вошел в систему» ​​displayName.

Я пытался протестировать _profile и displayName на длину и другие параметры, но есть кое-что, чего я просто не понимаю.

main.dart

import 'package:flutter/material.dart';
import 'auth.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String displayName = 'Not Signed In';

  Map<String, dynamic> _profile;
  bool _loading = false;

  @override
  initState() {
    super.initState();
    authService.profile.listen((state) => setState(() => _profile = state));
    authService.loading.listen((state) => setState(() => _loading = state));
    authService.user.toString();
  }

  @override
  Widget build(BuildContext context) {
    displayName = _profile == null
        ? 'Not Signed In'
        : '${_profile['displayName'].toString()}';
    if (displayName.length < 1) displayName = 'Not Signed In';

    return MaterialApp(
      title: 'FlutterBase',
      home: Scaffold(
          appBar: AppBar(
            title: Text('Flutterbase'),
            backgroundColor: Colors.amber,
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[LoginButton(), UserProfile()],
            ),
          ),
          drawer: Drawer(
            child: ListView(
              children: <Widget>[
                UserAccountsDrawerHeader(
                    accountName: Text(displayName), accountEmail: Text('gggg')),
                ListTile(
                  title: Text('Item 1'),
                )
              ],
            ),
          )),
    );
  }
}

class UserProfile extends StatefulWidget {
  @override
  UserProfileState createState() => UserProfileState();
}

class UserProfileState extends State<UserProfile> {
  Map<String, dynamic> _profile;
  bool _loading = false;

  @override
  initState() {
    super.initState();
    authService.profile.listen((state) => setState(() => _profile = state));
    authService.loading.listen((state) => setState(() => _loading = state));
    authService.user.toString();
  }

  @override
  Widget build(BuildContext context) {
    String displayName = _profile != null
        ? '${_profile['displayName'].toString()}'
        : 'Not signed in';

    String email =
        _profile != null ? _profile['email'].toString() : 'Not given';

    return Column(children: <Widget>[
      Container(padding: EdgeInsets.all(20), child: Text(_profile.toString())),
      Container(padding: EdgeInsets.all(20), child: Text(displayName)),
      Container(padding: EdgeInsets.all(20), child: Text(email)),
      Container(
          padding: EdgeInsets.all(20),
          child: Text('Loading: ${_loading.toString()}')),
    ]);
  }
}

class LoginButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: authService.user,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return MaterialButton(
              onPressed: () => authService.signOut(),
              color: Colors.red,
              textColor: Colors.white,
              child: Text('Signout'),
            );
          } else {
            return MaterialButton(
              onPressed: () => authService.googleSignIn(),
              color: Colors.white,
              textColor: Colors.black,
              child: Text('Login with Google'),
            );
          }
        });
  }
}

auth.dart

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

class AuthService {
  String userName;
  String userEmail;
  String userUid;

  final GoogleSignIn _googleSignIn = GoogleSignIn();
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final Firestore _db = Firestore.instance;

  Observable<FirebaseUser> user; //Firebase user
  Observable<Map<String, dynamic>> profile; // custom user data in Firestore
  PublishSubject loading = PublishSubject();

  // constructor
  AuthService() {
    user = Observable(_auth.onAuthStateChanged);
    profile = user.switchMap((FirebaseUser u) {
      if (u != null) {
        return _db
            .collection('users')
            .document(u.uid)
            .snapshots()
            .map((snap) => snap.data);
      } else {
        return Observable.just({});
      }
    });
  }

  Future<FirebaseUser> googleSignIn() async {
    try {
      loading.add(true);
      GoogleSignInAccount googleUser = await _googleSignIn.signIn();
      GoogleSignInAuthentication googleAuth = await googleUser.authentication;
      final AuthCredential credential = GoogleAuthProvider.getCredential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );
      FirebaseUser user = await _auth.signInWithCredential(credential);

      updateUserData(user);
      print("signed in " + user.displayName);
      loading.add(false);

      //see if this works
      userName = user.displayName;
      userEmail = user.email;
      userUid = user.uid;

      return user;
    } catch (error) {
      return error;
    }
  }

  void updateUserData(FirebaseUser user) async {
    DocumentReference ref = _db.collection('users').document(user.uid);

    return ref.setData({
      'uid': user.uid,
      'email': user.email,
      'photoURL': user.photoUrl,
      'displayName': user.displayName,
      'lastSeen': DateTime.now()
    }, merge: true); // makes not destructive update
  }

  Future<String> signOut() async {
    try {
      await _auth.signOut();
      return 'SignOut';
    } catch (e) {
      return e.toString();
    }
  }
}

final AuthService authService = AuthService();

1 Ответ

2 голосов
/ 09 мая 2019

Вы проверяете, является ли _profile значением null, что, скорее всего, хорошо до того, как пользователь вошел в систему, но я подозреваю, что _profile не устанавливается на null, когда пользователь впоследствии вышел из системы.

Я подозреваю, что эта строка кода return Observable.just({}); является проблемой, которая возвращает пустую карту вместо null, когда FirebaseUser равен null.

Вы можете попытаться вернуть туда null вместо пустой карты, хотя я не уверен, что это сработает.В противном случае вы можете добавить проверку isNotEmpty в дополнение к проверке null, например,

String displayName =
    (_profile != null && _profile.isNotEmpty) ? '${_profile['displayName'].toString()}' : 'Not 
signed in';

Надеюсь, что это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...