简体   繁体   中英

MediaQuery problem setting up Firebase with Flutter (Firebase)

So I wanted to add firebase_auth to my app and I ended up here https://firebase.flutter.dev/docs/overview/#initializing-flutterfire

So when I copy the code to set it up (I followed both of the approaches that they give but in this case, I am using the Stateful Widget one) the next error pops up.

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building FirebaseLoading:
MediaQuery.of() called with a context that does not contain a MediaQuery.
No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of().
This can happen because you do not have a WidgetsApp or MaterialApp widget (those widgets introduce
a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.
The context used was:
  Scaffold
The relevant error-causing widget was:
  FirebaseLoading
lib\main.dart:63
When the exception was thrown, this was the stack:

Apparently, somehow, the context that this widget creates doesn't have a MediaQuery so when the children (FirebaseLoading()) tries to access it to display a loading message it can't:

Here is the code of FirebaseLoading() btw:

import 'package:flutter/material.dart';

class FirebaseLoading extends StatelessWidget {
  const FirebaseLoading({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Loading"),
      ),
    );
  }
}

And here is the main class where FirebaseLoading is called:

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:qrcode_test/Models/Cart.dart';
import 'package:qrcode_test/Models/User.dart';
import 'Views/Controller.dart';
import 'Views/FirebaseError.dart';
import 'Views/FirebaseLoading.dart';

void main() {
  // WidgetsFlutterBinding.ensureInitialized();
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(builder: (context) => Cart(bundles: [])),
        ChangeNotifierProvider(builder: (context) => User()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatefulWidget {
  _AppState createState() => _AppState();
}

class _AppState extends State<MyApp> {
  // Set default `_initialized` and `_error` state to false
  bool _initialized = false;
  bool _error = false;

  // Define an async function to initialize FlutterFire
  void initializeFlutterFire() async {
    try {
      // Wait for Firebase to initialize and set `_initialized` state to true
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch (e) {
      // Set `_error` state to true if Firebase initialization fails
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // Show error message if initialization failed
    if (_error) {
      return FirebaseError();
    }

    // Show a loader until FlutterFire is initialized
    if (!_initialized) {
      return FirebaseLoading();
    }

    return Controller();
  }
}

I don't know if the multiproviders that I was using in the app can be causing any kind of problem but I don't think so.

Okay, it's not enought to call the widget over there, it has to be inside of a MaterialWidget like so:

@override
  Widget build(BuildContext context) {
    // Show error message if initialization failed
    if (_error) {
      return new MaterialApp(
        title: "My Cashier",
        theme: defaultTheme,
        home: new FirebaseError(),
      );
    }

    // Show a loader until FlutterFire is initialized
    if (!_initialized) {
      return new MaterialApp(
        title: "My Cashier",
        theme: defaultTheme,
        home: new FirebaseLoading(),
      );
    }

    return new MaterialApp(
      title: "My Cashier",
      theme: defaultTheme,
      home: new Controller(),
    );
  }

There is for sure a way not to repeat the MaterialApp, the title and the theme but I am tired...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM