如何正确初始化类?扑

时间:2020-05-20 11:38:50

标签: firebase flutter firebase-authentication

我正在使我的应用程序也可以在Web上运行,并且因为我需要Firebase实时数据库,远程配置和存储,所以我发现对于Web,我应该改用firebase软件包。 当我使用flutter_bloc / repository模式时,我实现了stub / abstract类/ implementation类模式来根据平台切换存储库。 到目前为止,设备应用程序上的所有内容都像以前一样正常工作。

现在访问Web应用程序,我做了一个singleton类,因此可以调用它并初始化Firebase App一次,然后在Web上运行时可以从我的应用程序中的任何位置访问所有服务。

我面临的问题是初始化only static members can be accessed in initializers Web存储库时得到Auth _firebaseAuth;。 我尝试使用方法直接在类构造器中(类似于上面评论的设备存储库构造器)对其进行初始化,但是两种方式都出现错误。 我如何正确初始化它? 一如既往,非常感谢您的时间和帮助。

这是单例:

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:firebase/firebase.dart';


class FirebaseWeb {
  // Singleton instance
  static final FirebaseWeb _singleton = FirebaseWeb._();

  // Singleton accessor
  static FirebaseWeb get instance => _singleton;

  // Completer is used for transforming synchronous code into asynchronous code.
  Completer<App> _dbOpenCompleter;

  // A private constructor. Allows us to create instances of AppDatabase
  // only from within the AppDatabase class itself.
  FirebaseWeb._();

  // Sembast database object
//  Database _database;

  // Database object accessor

  Future<App> get app async {
    // If completer is null, AppDatabaseClass is newly instantiated, so database is not yet opened
    if (_dbOpenCompleter == null) {
      _dbOpenCompleter = Completer();
      // Calling _openDatabase will also complete the completer with database instance
      _initializeApp();
    }
    // If the database is already opened, awaiting the future will happen instantly.
    // Otherwise, awaiting the returned future will take some time - until complete() is called
    // on the Completer in _openDatabase() below.
    return _dbOpenCompleter.future;
  }

  Future _initializeApp() async {
    initializeApp(
        name: 'xxx',
        apiKey: "xxx",
        authDomain: "xxx",
        databaseURL: "xxx",
        projectId: "xxx",
        storageBucket: "xxx",
        messagingSenderId: "xxx",
        appId: "xxx");
    _dbOpenCompleter.complete();
  }
}

这是Web存储库:

import 'package:firebase/firebase.dart';
import 'package:firebase/src/auth.dart';
import 'package:fixit_shop_flutter/fixit_shop_app/authentication_bloc/fixit_user.dart';
import 'package:fixit_shop_flutter/fixit_shop_app/platform_firebase_database/firebase_singleton.dart';
import 'package:fixit_shop_flutter/fixit_shop_app/platform_user_repository/platform_user_repository_switcher.dart';
import 'package:google_sign_in/google_sign_in.dart';

class UserRepositoryWeb implements UserRepository {
//  final FirebaseAuth _firebaseAuth;
  Auth
      _firebaseAuth; // = _Auth() ;//only static members can be accessed in initializers

//  App app = FirebaseWeb.instance.app as App;
//  Future<App> get _app async => FirebaseWeb.instance.app;

  final GoogleSignIn _googleSignIn; // = GoogleSignIn();

//  UserRepository({FirebaseAuth firebaseAuth, GoogleSignIn googleSignIn})
//      : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
//        _googleSignIn = googleSignIn ?? GoogleSignIn();

  UserRepositoryWeb({Auth firebaseAuth, GoogleSignIn googleSignIn})
      : _firebaseAuth = firebaseAuth ??
            _Auth(), //only static members can be accessed in initializers
        _googleSignIn = googleSignIn ?? GoogleSignIn();

  void _Auth() async {
    App app = FirebaseWeb.instance.app as App;
    _firebaseAuth = app.auth();
  }

//  Future<FirebaseUser> signInWithGoogle() async {
  Future<User> signInWithGoogle() async {
    print('signInWithGoogle() started');
    final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
    print('GoogleUser is : $googleUser');
    final GoogleSignInAuthentication googleAuth =
        await googleUser.authentication;
//    final AuthCredential credential = await GoogleAuthProvider.getCredential(
//        idToken: googleAuth.idToken, accessToken: googleAuth.accessToken);
    final OAuthCredential credential = await GoogleAuthProvider.credential(
        googleAuth.idToken, googleAuth.accessToken);
    await _firebaseAuth.signInWithCredential(credential);
//    return _firebaseAuth.currentUser();
    return _firebaseAuth.currentUser;
  }

//  Future<void> signInWithCredential({String email, String password}) {
//    return _firebaseAuth.signInWithEmailAndPassword(
//        email: email, password: password);
//  }
  Future<void> signInWithCredential({String email, String password}) {
    return _firebaseAuth.signInWithEmailAndPassword(email, password);
  }

//  Future<void> signUp({String email, String password}) {
//    return _firebaseAuth.createUserWithEmailAndPassword(
//        email: email, password: password);
//  }
  Future<void> signUp({String email, String password}) {
    return _firebaseAuth.createUserWithEmailAndPassword(email, password);
  }

  Future<void> signOut() async {
    return Future.wait([
      _firebaseAuth.signOut(),
      _googleSignIn.signOut(),
    ]);
  }

  Future<bool> isSignedIn() async {
//    final currentUser = _firebaseAuth.currentUser();
    final currentUser = _firebaseAuth.currentUser;
    return currentUser != null;
  }

  Future<FixitUser> getUser() async {
    String displayName = (await _firebaseAuth.currentUser).displayName;
    String email = (await _firebaseAuth.currentUser).email;
    String uid = (await _firebaseAuth.currentUser).uid;
    String photoUrl = (await _firebaseAuth.currentUser).photoURL;
    String phoneNumber = (await _firebaseAuth.currentUser).phoneNumber;
    FixitUser user = FixitUser(
        name: displayName ?? '',
        email: email,
        phoneNumber: phoneNumber ?? '',
        uid: uid,
        photoUrl: photoUrl ?? '');
    return (user);
  }
}

UserRepository getUserRepository() => UserRepositoryWeb();

1 个答案:

答案 0 :(得分:0)

经过多次尝试,我终于对单例和Web实现类进行了微调。在我的单例中,我返回的是Future<App>,这将使得返回它比直接返回的App更为直接(请参见网络存储库中已注释掉的部分),因为我还没有掌握{{1} }我在调试代码时遇到了一些困难,因此我决定不使用它。

单人:

Completer()

网络存储库:

import 'dart:async';
import 'package:firebase/firebase.dart';

class FirebaseWeb {
  // Singleton instance
  static final FirebaseWeb _singleton = FirebaseWeb._();

  // Singleton accessor
  static FirebaseWeb get instance => _singleton;

  // Completer is used for transforming synchronous code into asynchronous code.
  Completer<App> _dbOpenCompleter;

  // A private constructor. Allows us to create instances of AppDatabase
  // only from within the AppDatabase class itself.
  FirebaseWeb._();

  static App _app;
  // Database object accessor

  App get app {
    print('firebase get app called ');
    print('_app is $_app');
    if (_app != null) {
      return _app;
    } else {
      print('initialize app');
      _app = initializeApp(
          apiKey: "xxx",
          authDomain: "xxx",
          databaseURL: "xxx",
          projectId: "xxx",
          storageBucket: "xxx",
          messagingSenderId: "xxx",
          appId: "xxx");
      return _app;
    }
  }

}