Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use it without the mock service #19

Closed
premtemp1 opened this issue Jun 18, 2019 · 7 comments
Closed

How to use it without the mock service #19

premtemp1 opened this issue Jun 18, 2019 · 7 comments
Labels
question Further information is requested

Comments

@premtemp1
Copy link

Hello,
Thanks for the article.. I like the mock service but I don't want to use it now.. Do I still need the adapter class?

Thanks

@bizz84
Copy link
Owner

bizz84 commented Jun 19, 2019

No you don't.
Simply inject FirebaseAuthService() into your provider in main.dart:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<AuthService>(
      builder: (_) => FirebaseAuthService(),
      dispose: (_, AuthService authService) => authService.dispose(),
      child: MaterialApp(
        theme: ThemeData(
          primarySwatch: Colors.indigo,
        ),
        home: LandingPage(),
      ),
    );
  }
}

As a result, you could also remove the dispose() method from both AuthService and FirebaseAuthService (this was only needed as the adapter uses StreamControllers that need to be disposed).

@bizz84 bizz84 added the question Further information is requested label Jun 19, 2019
@bizz84 bizz84 closed this as completed Jun 19, 2019
@premtemp1
Copy link
Author

Thanks..
Please consider doing a deep dive on how to create a lazy loading list that get another set of record when the user scroll to the end. The list should scroll backward and forward and save the previous position...
The API should take a page could and number of record to display

Thanks

@MRANASSPRO
Copy link

MRANASSPRO commented Aug 8, 2019

@bizz84 well I receive this error every time I try to signup while trying to implement your solution working only with FirebaseAuthService(), and also getting rid of the dispose() method:

E/flutter (32103): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: A SignInModel was used after being disposed.
E/flutter (32103): Once you have called dispose() on a SignInModel, it can no longer be used.
E/flutter (32103): #0 _SignInModel&Object&EmailAndPasswordValidators&ChangeNotifier._debugAssertNotDisposed. (package:flutter/src/foundation/change_notifier.dart:105:9)
E/flutter (32103): #1 _SignInModel&Object&EmailAndPasswordValidators&ChangeNotifier._debugAssertNotDisposed (package:flutter/src/foundation/change_notifier.dart:111:6)
E/flutter (32103): #2 _SignInModel&Object&EmailAndPasswordValidators&ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:200:12)
E/flutter (32103): #3 SignInModel.updateWith (package:firebase_auth_demo_flutter/app/sign_in/sign_in_model.dart:77:5)
E/flutter (32103): #4 SignInModel.submit (package:firebase_auth_demo_flutter/app/sign_in/sign_in_model.dart:47:7)
E/flutter (32103):

@bizz84
Copy link
Owner

bizz84 commented Aug 8, 2019

@MRANASSPRO That's curious, that doesn't happen to me. Can you post the code for the sign in page that generates the error?

@MRANASSPRO
Copy link

MRANASSPRO commented Aug 8, 2019

Pretty much the same code in the master branch, just got rid of the mock service, using only the FirebaseAuthService() as the provider´s builder, the error is being generated when clicking on the submit button on either sign up or sign in.
Here is updated sign_in_page:

import 'package:firebase_auth_demo_flutter/app/sign_in/sign_in_model.dart';
import 'package:firebase_auth_demo_flutter/common_widgets/form_submit_button.dart';
import 'package:firebase_auth_demo_flutter/common_widgets/platform_alert_dialog.dart';
import 'package:firebase_auth_demo_flutter/common_widgets/platform_exception_alert_dialog.dart';
import 'package:firebase_auth_demo_flutter/constants/strings.dart';
import 'package:firebase_auth_demo_flutter/services/auth_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';

class SignInPageBuilder extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final AuthService auth = Provider.of<AuthService>(context);
    return ChangeNotifierProvider<SignInModel>(
      builder: (_) => SignInModel(auth: auth),
      child: Consumer<SignInModel>(
        builder: (_, SignInModel model, __) => SignInPage._(model: model),
      ),
    );
  }
}

class SignInPage extends StatefulWidget {
  const SignInPage._({Key key, @required this.model}) : super(key: key);
  final SignInModel model;

  @override
  _SignInPageState createState() => _SignInPageState();
}

class _SignInPageState extends State<SignInPage> {
  final FocusNode _emailFocusNode = FocusNode();
  final FocusNode _passwordFocusNode = FocusNode();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  SignInModel get model => widget.model;

  @override
  void dispose() {
    _emailFocusNode.dispose();
    _passwordFocusNode.dispose();
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  void _showSignInError(SignInModel model, PlatformException exception) {
    PlatformExceptionAlertDialog(
      title: model.errorAlertTitle,
      exception: exception,
    ).show(context);
  }

  void _unfocus() {
    _emailFocusNode.unfocus();
    _passwordFocusNode.unfocus();
  }

  Future<void> _submit() async {
    _unfocus();
    try {
      final bool success = await model.submit();
      if (success) {
        if (model.formType == SignInFormType.forgotPassword) {
          PlatformAlertDialog(
            title: Strings.resetLinkSentTitle,
            content: Strings.resetLinkSentMessage,
            defaultActionText: Strings.ok,
          ).show(context);
        } else {
          //print('context check: $context ');
          Navigator.of(context).pop();
        }
      }
    } on PlatformException catch (e) {
      _showSignInError(model, e);
    }
  }

  void _emailEditingComplete() {
    final FocusNode newFocus = model.canSubmitEmail ? _passwordFocusNode : _emailFocusNode;
    FocusScope.of(context).requestFocus(newFocus);
  }

  void _updateFormType(SignInFormType formType) {
    model.updateFormType(formType);
    _emailController.clear();
    _passwordController.clear();
  }

  Widget _buildEmailField() {
    return TextField(
      controller: _emailController,
      focusNode: _emailFocusNode,
      decoration: InputDecoration(
        labelText: Strings.emailLabel,
        hintText: Strings.emailHint,
        errorText: model.emailErrorText,
        enabled: !model.isLoading,
      ),
      autocorrect: false,
      textInputAction: TextInputAction.next,
      keyboardType: TextInputType.emailAddress,
      keyboardAppearance: Brightness.light,
      onChanged: model.updateEmail,
      onEditingComplete: _emailEditingComplete,
      inputFormatters: <TextInputFormatter>[
        model.emailInputFormatter,
      ],
    );
  }

  Widget _buildPasswordField() {
    return TextField(
      controller: _passwordController,
      focusNode: _passwordFocusNode,
      decoration: InputDecoration(
        labelText: model.passwordLabelText,
        errorText: model.passwordErrorText,
        enabled: !model.isLoading,
      ),
      obscureText: true,
      autocorrect: false,
      textInputAction: TextInputAction.done,
      keyboardAppearance: Brightness.light,
      onChanged: model.updatePassword,
      onEditingComplete: _submit,
    );
  }

  Widget _buildContent() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        SizedBox(height: 8.0),
        _buildEmailField(),
        if (model.formType != SignInFormType.forgotPassword) ...<Widget>[
          SizedBox(height: 8.0),
          _buildPasswordField(),
        ],
        SizedBox(height: 8.0),
        FormSubmitButton(
          text: model.primaryButtonText,
          loading: model.isLoading,
          onPressed: model.isLoading ? null : _submit,
        ),
        SizedBox(height: 8.0),
        FlatButton(
          child: Text(model.secondaryButtonText),
          onPressed: model.isLoading ? null : () => _updateFormType(model.secondaryActionFormType),
        ),
        if (model.formType == SignInFormType.signIn)
          FlatButton(
            child: Text(Strings.forgotPasswordQuestion),
            onPressed: model.isLoading ? null : () => _updateFormType(SignInFormType.forgotPassword),
          ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 2.0,
        title: Text(model.title),
      ),
      backgroundColor: Colors.grey[200],
      body: SingleChildScrollView(
        child: Padding(
          padding: EdgeInsets.all(16.0),
          child: Card(
            child: Padding(
              padding: EdgeInsets.all(16.0),
              child: _buildContent(),
            ),
          ),
        ),
      ),
    );
  }
}

@bizz84
Copy link
Owner

bizz84 commented Aug 17, 2019

@MRANASSPRO sorry for the late reply.
Do you present the sign-in page with a call to Navigator.push, or is it built at the root of the navigation stack?

@MRANASSPRO
Copy link

@bizz84 Hey Andrea, I am really sorry that was my mistake, I removed the SignInPageBuilder class, that contains a Provider of AuthService, now I fixed it and it worked perfectly :)
I will remove the issue, my sincere apologies
I am looking forward to contact you via email if possible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants