This is a question mostly about the best practice, I'm new to flutter dev and to the BLoC architecture, to summarize I have an app that has an app_bloc which handles user authentication (firebase login), it's pretty simple, has two states Authenticated and Unauthenticated.
My app renders pages depending on whether user is authenticated or not, either login page or home page.
import 'package:authentication_repository/authentication_repository.dart';
import 'package:flow_builder/flow_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:majstor/app/bloc/app_bloc.dart';
import 'package:majstor/app/routes/routes.dart';
import 'package:majstor/theme.dart';
class App extends StatelessWidget {
const App({
Key? key,
required AuthenticationRepository authenticationRepository,
}) : _authenticationRepository = authenticationRepository,
super(key: key);
final AuthenticationRepository _authenticationRepository;
@override
Widget build(BuildContext context) {
return RepositoryProvider.value(
value: _authenticationRepository,
child: BlocProvider(
create: (_) => AppBloc(
authenticationRepository: _authenticationRepository,
),
child: const AppView(),
),
);
}
}
class AppView extends StatelessWidget {
const AppView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
/// try context.select here maybe?
return MaterialApp(
home: FlowBuilder<AppStatus>(
state: context.select((AppBloc bloc) => bloc.state.status),
onGeneratePages: onGenerateAppViewPages,
),
);
}
}
import 'package:flutter/widgets.dart';
import 'package:majstor/app/app.dart';
import 'package:majstor/home/home.dart';
import 'package:majstor/login/login.dart';
List<Page> onGenerateAppViewPages(AppStatus state, List<Page<dynamic>> pages) {
switch (state) {
case AppStatus.authenticated:
return [HomePage.page()];
case AppStatus.unauthenticated:
default:
return [LoginPage.page()];
}
}
Now what I'm having a hard time wrapping my head around is this, in my home page case, I'd like to further 'split' my users into roles, there will be two roles stored on a Firebase collection with the user's corresponding id on the same document, and for each role a different page entirely should be built, I'm not sure where exactly would I do this role check, I could technically in the home page below, query the database by using the user id, and getting the role and then similarly as i did with the login and home, use a flowbuilder to generate different page depending on role? But is that a good practice? I kind of feel like I should be separating the database logic elsewhere, but as I'm new to this kind of development I don't know where I should be doing this to build a scalable app.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:majstor/app/app.dart';
import 'package:majstor/home/home.dart';
import 'package:majstor/utils/databaseservice.dart';
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
static Page page() => const MaterialPage<void>(child: HomePage());
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final user = context.select((AppBloc bloc) => bloc.state.user);
Database db = Database();
db.readData(user.id);
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
actions: <Widget>[
IconButton(
key: const Key('homePage_logout_iconButton'),
icon: const Icon(Icons.exit_to_app),
onPressed: () => context.read<AppBloc>().add(AppLogoutRequested()),
)
],
),
body: Align(
alignment: const Alignment(0, -1 / 3),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Avatar(photo: user.photo),
const SizedBox(height: 4),
Text(user.email ?? '', style: textTheme.headline6),
const SizedBox(height: 4),
Text(user.name ?? '', style: textTheme.headline5),
],
),
),
);
}
}
Do I query the database in the file above, and do the checks there or, is there a way to sort of separate my logic further? Should I be using BloCs for roles aswell? or should I be somehow integrating roles into my existing BloC? Hope I was clear enough with my explanation.
So I'm not a Flutter developer, but I might be able to offer some advice based on my general experience and some research I did for your question. And I'm assuming your concept of Bloc's align's somewhat with this.
I'd like to further 'split' my users into roles ... I'm not sure where exactly would I do this role check
Do I query the database in the file above, and do the checks there or, is there a way to sort of separate my logic further? Should I be using BloCs for roles as well?