首页 > 解决方案 > 如何正确初始化类?扑

问题描述

我正在调整我的应用程序以在 web 上运行,并且由于我需要 firebase 实时数据库、远程配置和存储,我看到对于 web 我应该使用firebase包来代替。当我使用flutter_bloc/repository 模式时,我实现了存根/抽象类/实现类模式来根据平台切换存储库。到目前为止,设备应用程序上的一切都像以前一样正常工作。

现在解决网络应用程序,我创建了一个单例类,这样我就可以调用它并初始化一个 Firebase 应用程序,然后在网络上运行时从我的应用程序中的任何点访问所有服务。

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

这是单例:

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

这是网络存储库:

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

标签: firebaseflutterfirebase-authentication

解决方案


经过多次尝试,我终于对单例和 Web 实现类进行了微调。在我的单例中,我返回了 a Future<App>,这会使使用它比返回 a 更直接(参见 web 存储库中注释掉的部分)App,而且我还没有掌握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;
    }
  }

}

网络存储库:

import 'dart:async';
import 'package:firebase/firebase.dart';
import 'package:firebaseblocwebstub/authentication_bloc/app_user.dart';
import 'package:firebaseblocwebstub/firebase_singleton.dart';
import 'package:firebaseblocwebstub/platform_user_repository/platform_user_repository_switcher.dart';
import 'package:google_sign_in/google_sign_in.dart';

class UserRepositoryWeb implements UserRepositorySwitcher {
  App firebase = FirebaseWeb.instance.app;
  final GoogleSignIn _googleSignIn = GoogleSignIn();

  Future<User> signInWithGoogle() async {
    print('signInWithGoogle() started');
    final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
    print('GoogleUser is : $googleUser');
    final GoogleSignInAuthentication googleAuth =
        await googleUser.authentication;
    final OAuthCredential credential = await GoogleAuthProvider.credential(
        googleAuth.idToken, googleAuth.accessToken);
    // singleton retunrning Future<App>
//    await firebase.then((firebase) {
//      firebase.auth().signInWithCredential(credential);
//      return;
//    });
//    return firebase.then((firebase) {
//      return firebase.auth().currentUser;
//    });

    await firebase.auth().signInWithCredential(credential);
    return firebase.auth().currentUser;
  }

  Future<void> signInWithCredential({String email, String password}) {
    return firebase.auth().signInWithEmailAndPassword(email, password);
    // singleton retunrning Future<App>
//    return firebase.then((firebase) {
//      return firebase.auth().signInWithEmailAndPassword(email, password);
//    });
  }

  Future<void> signUp({String email, String password}) {
    return firebase.auth().createUserWithEmailAndPassword(email, password);
    // singleton retunrning Future<App>
//    return firebase.then((firebase) {
//      return firebase.auth().createUserWithEmailAndPassword(email, password);
//    });
  }

  Future<void> signOut() async {
    return Future.wait([
      firebase.auth().signOut(),
// singleton retunrning Future<App>
//      firebase.then((firebase) {
//        firebase.auth().signOut();
//      }),
      _googleSignIn.signOut(),
    ]);
  }

  Future<bool> isSignedIn() async {
    final currentUser = firebase.auth().currentUser;
    return currentUser != null;
    // singleton retunrning Future<App>
//    User firebaseUser = firebase.then((firebase) {
//      return firebase.auth().currentUser;
//    }) as User;
//    return firebaseUser != null;
  }

  Future<FixitUser> getUser() async {
    // singleton retunrning Future<App>
//    User firebaseUser = firebase.then((firebase) {
//      return firebase.auth().currentUser;
//    }) as User;
//
//    FixitUser user = FixitUser(
//        name: firebaseUser.displayName ?? '',
//        email: firebaseUser.email,
//        phoneNumber: firebaseUser.phoneNumber ?? '',
//        uid: firebaseUser.uid,
//        photoUrl: firebaseUser.photoURL ?? '');
//    return (user);
//  }
    String displayName = (firebase.auth().currentUser).displayName;
    String email = (firebase.auth().currentUser).email;
    String uid = (firebase.auth().currentUser).uid;
    String photoUrl = (firebase.auth().currentUser).photoURL;
    String phoneNumber = (firebase.auth().currentUser).phoneNumber;

    FixitUser user = FixitUser(
        name: displayName ?? '',
        email: email,
        phoneNumber: phoneNumber ?? '',
        uid: uid,
        photoUrl: photoUrl ?? '');
    return (user);
  }
}

UserRepositorySwitcher getUserRepository() => UserRepositoryWeb();

推荐阅读