I'm using flutter web and firebase. I'm using firebase Auth's email authentication, and there are two problems.
- When refresh the web, authentication is disconnected.
- Sometimes there is a problem of falling into infinite loading when logging in
I used almost the same code that I made in the previous app, and when I run it on the app, it works fine.
pubspec.yaml
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
firebase_core: ^0.5.0
firebase_auth: ^0.18.0
cloud_firestore: ^0.14.0
firebase_storage: ^4.0.0
flutter_web_frame: ^0.0.2 #Web size
carousel_slider: ^3.0.0
get: ^3.3.0
cached_network_image: ^2.2.0+1
provider: ^4.3.3
google_sign_in: ^4.5.9
index.html
</script>
<script src = "https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.22.1/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-storage.js"></script>
<script>
var firebaseConfig = {
apiKey: ,
authDomain: ,
projectId: ,
storageBucket: ,
messagingSenderId: ,
appId: ,
measurementId:
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.getAnalytics(app);
</script>
This is part of my authentication code.
firebase_auth_state.dart
enum FirebaseAuthStatus { signout, progress, signin }
class FirebaseAuthState extends ChangeNotifier {
FirebaseAuthStatus _firebaseAuthStatus = FirebaseAuthStatus.progress;
FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
User _firebaseUser;
//check user state
void watchAuthChange() {
_firebaseAuth.authStateChanges().listen((firebaseUser) {
//when first
if (firebaseUser == null && _firebaseUser == null) {
changeFirebaseAuthStatus();
return;
//firebaseUser update
} else if (firebaseUser != _firebaseUser) {
_firebaseUser = firebaseUser;
//auth state change check
changeFirebaseAuthStatus();
}
});
}
void changeFirebaseAuthStatus([FirebaseAuthStatus firebaseAuthStatus]) {
if (firebaseAuthStatus != null) {
_firebaseAuthStatus = firebaseAuthStatus;
} else {
if (_firebaseUser != null) {
_firebaseAuthStatus = FirebaseAuthStatus.signin;
} else {
_firebaseAuthStatus = FirebaseAuthStatus.signout;
}
}
notifyListeners();
}
void registerUser(BuildContext context,
{@required String email, @required String password}) async {
if (_firebaseUser != null) {
//loading
changeFirebaseAuthStatus(FirebaseAuthStatus.progress);
}
UserCredential userCredential = await _firebaseAuth
.createUserWithEmailAndPassword(
email: email.trim(),
password: password.trim())
_firebaseUser = userCredential.user;
if (_firebaseUser == null) {
SnackBar snackBar = SnackBar(
content: Text("error?"),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
} else {
//User firestore upload
userNetworkRepo.attempCreatUser(
userKey: _firebaseUser.uid,
userEmail: _firebaseUser.email);
}
}
void signIn(BuildContext context,
{@required String email, @required String password}) async {
if (_firebaseUser != null) {
changeFirebaseAuthStatus(FirebaseAuthStatus.progress);
}
UserCredential userCredential = await _firebaseAuth
.signInWithEmailAndPassword(
email: email.trim(), password: password.trim())
.catchError((error) {
print(error);
}
_firebaseUser = userCredential.user;
if (_firebaseUser == null) {
SnackBar snackBar = SnackBar(
content: Text("error?"),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
void signOut() async {
changeFirebaseAuthStatus(FirebaseAuthStatus.progress);
_firebaseAuthStatus = FirebaseAuthStatus.signout;
if (_firebaseUser != null) {
_firebaseUser = null;
_firebaseAuth.signOut();
}
notifyListeners();
}
//create instance
FirebaseAuthStatus get firebaseAuthStatus => _firebaseAuthStatus;
User get firebaseUser => _firebaseUser;
}
And in main.dart, sign in or sign out according to the authentication status.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
FirebaseAuthState _firebaseAuthState = FirebaseAuthState();
//current auth state
Widget _currentWidget;
@override
Widget build(BuildContext context) {
_firebaseAuthState.watchAuthChange();
//Web max size
return FlutterWebFrame(
builder: (BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<FirebaseAuthState>.value(
value: _firebaseAuthState),
ChangeNotifierProvider<UserModelState>(
create: (_) => UserModelState(),
),
],
child: GetMaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: white,
),
home: Consumer<FirebaseAuthState>(
builder: (BuildContext context, FirebaseAuthState firebaseAuthState,
Widget child) {
switch (firebaseAuthState.firebaseAuthStatus) {
case FirebaseAuthStatus.signout:
_clearUserModel(context);
_currentWidget = AuthScreen();
break;
case FirebaseAuthStatus.signin:
_initUserModel(firebaseAuthState, context);
_currentWidget = HomeScreen();
break;
default:
_currentWidget = CustomLoading();
break;
}
return AnimatedSwitcher(
duration: Duration(milliseconds: 300),
child: _currentWidget,
);
},
),
),
);
},
//Web max size
maximumSize: Size(768.0, 1024.0),
enabled: true,
);
}
//userModel update
_initUserModel(FirebaseAuthState firebaseAuthState, BuildContext context) {
UserModelState userModelState =
Provider.of<UserModelState>(context, listen: false);
// if (userModelState.currentStreamSub == null) {
userModelState.currentStreamSub = userNetworkRepo
.getUserModelStream(firebaseAuthState.firebaseUser.uid)
.listen((userModel) {
userModelState.userModel = userModel;
print('userModel: ${userModel.username} , ${userModel.userKey}');
});
}
_clearUserModel(BuildContext context) {
UserModelState userModelState =
Provider.of<UserModelState>(context, listen: false);
userModelState.clear();
}
}
The biggest problem is that sometimes I can't signIn well. May I know the cause and solution of this?
Thank you!
Aucun commentaire:
Enregistrer un commentaire