首页 > 解决方案 > 错误:云找不到正确的提供者> 在此 BrewList 小部件上方

问题描述

我正在尝试从 Firestore 检索基于自动更新的 stepcountvalue。不知何故有一个错误,我只是不知道为什么......

这是我的 main.dart

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_testing/models/brew.dart';
import 'package:flutter_testing/models/user.dart';
import 'package:flutter_testing/screens/Pages/page.dart';
import 'package:flutter_testing/screens/wrapper.dart';
import 'package:flutter_testing/services/auth.dart';
import 'package:flutter_testing/services/database.dart';
import 'dart:async';
import 'package:percent_indicator/circular_percent_indicator.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:pedometer/pedometer.dart';
import 'package:provider/provider.dart';

void main() => runApp(new NewApp());

class NewApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: AuthService().user,
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}



class MyApp extends StatefulWidget {

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

class _MyAppState extends State<MyApp> {

  final AuthService _auth = AuthService();

  String muestrePasos = "";
  String _km = "Unknown";
  String _calories = "Unknown";
  String stepCountValue = 'Unknown';
  String _showcoin = '0';

  StreamSubscription<int> _subscription;

  double _numerox; //numero pasos
  double _convert;
  double _kmx;
  double burnedx;
  double _coin;
  double _porciento;
  // double percent=0.1;

  @override
  void initState() {
    super.initState();
    //initPlatformState();
    setUpPedometer();
  }

  //inicia codigo pedometer
  void setUpPedometer() {
    Pedometer pedometer = new Pedometer();
    _subscription = pedometer.stepCountStream.listen(_onData,
        onError: _onError, onDone: _onDone, cancelOnError: true);
  }

  void _onData(int stepCountValue1) async {
    // print(stepCountValue); //impresion numero pasos por consola
    setState(() {
      stepCountValue = "$stepCountValue1";
      // print(stepCountValue);
    });

    var dist = stepCountValue1; //pasamos el entero a una variable llamada dist
    double y = (dist + .0); //lo convertimos a double una forma de varias

    setState(() {
      _numerox = y; //lo pasamos a un estado para ser capturado ya convertido a double
    });

    var long3 = (_numerox);
    long3 = num.parse(y.toStringAsFixed(2));
    var long4 = (long3 / 10000);

    int decimals = 1;
    int fac = pow(10, decimals);
    double d = long4;
    d = (d * fac).round() / fac;
    print("d: $d");

    getDistanceRun(_numerox);

    setState(() {
      _convert = d;
      print(_convert);
    });
  }

  void reset() {
    setState(() {
      int stepCountValue1 = 0;
      stepCountValue1 = 0;
      stepCountValue = "$stepCountValue1";
    });
  }

  void _onDone() {}

  void _onError(error) {
    print("Flutter Pedometer Error: $error");
  }

  //function to determine the distance run in kilometers using number of steps
  void getDistanceRun(double _numerox) {
    var distance = ((_numerox * 76) / 100000);
    distance = num.parse(distance.toStringAsFixed(2)); //dos decimales
    var distancekmx = distance * 34;
    distancekmx = num.parse(distancekmx.toStringAsFixed(2));
    //print(distance.runtimeType);
    var coiny = ((_numerox * 125) / 100000);
    coiny = num.parse(coiny.toStringAsFixed(2));

    setState(() {
      _km = "$distance";
      //print(_km);
    });
    setState(() {
      _kmx = num.parse(distancekmx.toStringAsFixed(2));
    });

    setState(() {
      _coin = num.parse(coiny.toStringAsFixed(2));
      //print(_coiny);
    });
  }

  //function to determine the calories burned in kilometers using number of steps
  void getBurnedRun() {
    setState(() {
      var calories = _kmx; //dos decimales
      _calories = "$calories";
      //print(_calories);
    });
  }

  void coins() {
    setState(() {
      var showcoin = _coin;
      _showcoin = "$showcoin";
    });
  }

  //fin codigo pedometer

  @override
  Widget build(BuildContext context) {
    //print(_stepCountValue);
    getBurnedRun();
    coins();
    return StreamProvider<List<Brew>>.value(
        value: DatabaseService().step,
        child: MaterialApp(
          debugShowCheckedModeBanner: false,
          home: new Scaffold(
            appBar: new AppBar(
              title: const Text('Step Counter'),
              backgroundColor: Colors.black54,
              actions: <Widget>[
                FlatButton.icon(
                    icon: Icon(Icons.person),
                    label: Text('logout'),
                    onPressed: () async {
                      await _auth.signOut();
                    }
                ),
          FlatButton.icon(
            icon: Icon(Icons.arrow_back),
            label: Text('New Page'),
            onPressed: () {
              Navigator.of(context)
                  .push(MaterialPageRoute(builder: (context) => pages()));
            }
          ),
          ],
          ),

            body: new ListView(
              padding: EdgeInsets.all(5.0),
              children: <Widget>[
                Container(
                  padding: EdgeInsets.only(top: 10.0),
                  width: 250,
                  //ancho
                  height: 250,
                  //largo tambien por numero height: 300
                  decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment
                            .bottomCenter, //cambia la iluminacion del degradado
                        end: Alignment.topCenter,
                        colors: [Color(0xFFA9F5F2), Color(0xFF01DFD7)],
                      ),
                      borderRadius: BorderRadius.only(
                        bottomLeft: Radius.circular(27.0),
                        bottomRight: Radius.circular(27.0),
                        topLeft: Radius.circular(27.0),
                        topRight: Radius.circular(27.0),
                      )),
                  child: new CircularPercentIndicator(
                    radius: 200.0,
                    lineWidth: 13.0,
                    animation: true,
                    center: Container(
                      child: new Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                          Container(
                            height: 50,
                            width: 50,
                            padding: EdgeInsets.only(left: 20.0),
                            child: Icon(
                              FontAwesomeIcons.walking,
                              size: 30.0,
                              color: Colors.white,
                            ),
                          ),
                          Container(
                            //color: Colors.orange,
                            child: Text(
                              '$stepCountValue',
                              style: TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 20.0,
                                  color: Colors.purpleAccent),
                            ),
                            // height: 50.0,
                            // width: 50.0,
                          ),
                        ],
                      ),
                    ),
                    percent: 0.217,
                    //percent: _convert,
                    footer: new Text(
                      "Steps:  $stepCountValue",
                      style: new TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 12.0,
                          color: Colors.purple),
                    ),
                    circularStrokeCap: CircularStrokeCap.round,
                    progressColor: Colors.purpleAccent,
                  ),
                ),
                Divider(
                  height: 5.0,
                ),
                Container(
                  width: 80,
                  height: 100,
                  padding: EdgeInsets.only(left: 25.0, top: 10.0, bottom: 10.0),
                  color: Colors.transparent,
                  child: Row(
                    children: <Widget>[
                      new Container(
                        child: new Card(
                          child: Container(
                            height: 80.0,
                            width: 80.0,
                            decoration: BoxDecoration(
                              image: DecorationImage(
                                image: AssetImage("assets/images/distance.png"),
                                fit: BoxFit.fitWidth,
                                alignment: Alignment.topCenter,
                              ),
                            ),
                            child: Text(
                              "$_km Km",
                              textAlign: TextAlign.right,
                              style: new TextStyle(
                                  fontWeight: FontWeight.bold, fontSize: 14.0),
                            ),
                          ),
                          color: Colors.white54,
                        ),
                      ),
                      VerticalDivider(
                        width: 20.0,
                      ),
                      new Container(
                        child: new Card(
                          child: Container(
                            height: 80.0,
                            width: 80.0,
                            decoration: BoxDecoration(
                              image: DecorationImage(
                                image: AssetImage("assets/images/burned.png"),
                                fit: BoxFit.fitWidth,
                                alignment: Alignment.topCenter,
                              ),
                            ),
                          ),
                          color: Colors.transparent,
                        ),
                      ),
                      VerticalDivider(
                        width: 20.0,
                      ),
                      new Container(
                        child: new Card(
                          child: Container(
                            height: 80.0,
                            width: 80.0,
                            decoration: BoxDecoration(
                              image: DecorationImage(
                                image: AssetImage("assets/images/step.png"),
                                fit: BoxFit.fitWidth,
                                alignment: Alignment.topCenter,
                              ),
                            ),
                          ),
                          color: Colors.transparent,
                        ),
                      ),
                    ],
                  ),
                ),
                Divider(
                  height: 2,
                ),
                Container(
                  padding: EdgeInsets.only(top: 2.0),
                  width: 150,
                  //ancho
                  height: 30,
                  //largo tambien por numero height: 300
                  color: Colors.transparent,
                  child: Row(
                    children: <Widget>[
                      new Container(
                        padding: EdgeInsets.only(left: 40.0),
                        child: new Card(
                          child: Container(
                            child: Text(
                              "$_km Km",
                              textAlign: TextAlign.right,
                              style: new TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 14.0,
                                  color: Colors.white),
                            ),
                          ),
                          color: Colors.purple,
                        ),
                      ),
                      VerticalDivider(
                        width: 20.0,
                      ),
                      new Container(
                        padding: EdgeInsets.only(left: 10.0),
                        child: new Card(
                          child: Container(
                            child: Text(
                              "$_calories kCal",
                              textAlign: TextAlign.right,
                              style: new TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 14.0,
                                  color: Colors.white),
                            ),
                          ),
                          color: Colors.red,
                        ),
                      ),
                      VerticalDivider(
                        width: 5.0,
                      ),
                      new Container(
                        padding: EdgeInsets.only(left: 10.0),
                        child: new Card(
                          child: Container(
                            child: Text(
                              "$_showcoin Coins",
                              textAlign: TextAlign.right,
                              style: new TextStyle(
                                  fontWeight: FontWeight.bold,
                                  fontSize: 14.0,
                                  color: Colors.white),
                            ),
                          ),
                          color: Colors.black,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
    );
  }
}

这是我的 wrapper.dart

import 'package:flutter_testing/models/user.dart';
import 'package:flutter_testing/screens/authenticate/authenticate.dart';
import 'package:flutter/material.dart';
import 'package:flutter_testing/main.dart';
import 'package:provider/provider.dart';

class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    final user = Provider.of<User>(context);

    // return either the Home or Authenticate widget
    if (user == null){
      return Authenticate();
    } else {
      return MyApp();
    }

  }
}

这是 page.dart

import 'package:flutter/material.dart';
import 'package:flutter_testing/main.dart';
import 'brew_list.dart';

class pages extends StatefulWidget {
  @override
  _pagesState createState() => _pagesState();
}

class _pagesState extends State<pages> {
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      backgroundColor: Colors.amber,
        appBar: new AppBar(
          actions: <Widget>[
            FlatButton.icon(
              icon: Icon(Icons.arrow_back_ios),
              label: Text('back'), onPressed: () {
                Navigator.of(context)
                    .push(MaterialPageRoute(builder: (context) => MyApp())
                );
            }
            ),
          ],
        ),
      body: BrewList(),
    );
  }
}

这是database.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_testing/models/brew.dart';

class DatabaseService {

  final String uid;
  DatabaseService({ this.uid });

  // collection reference
  final CollectionReference brewCollection = Firestore.instance.collection('step');
  Future<void> updateUserData(int stepCountValue, int _calories, int _km , int _showcoin) async {
    return await brewCollection.document(uid).setData({
      'stepCountValue': stepCountValue,
      '_calories': _calories,
      '_km': _km,
      '_showcoin': _showcoin,
    });
  }

  // brew list from snapshot
  List<Brew> _brewListFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.documents.map((doc){
      return Brew(
        stepCountValue: doc.data['stepCountValue'] ?? 0,
      );
    }).toList();
  }

  // get brews stream
  Stream<List<Brew>> get step {
    return brewCollection.snapshots()
        .map(_brewListFromSnapshot);
  }

}

这是 brew_list.dart

import 'package:flutter_testing/models/brew.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'brew_tile.dart';

class BrewList extends StatefulWidget {
  @override
  _BrewListState createState() => _BrewListState();
}

class _BrewListState extends State<BrewList> {
  @override
  Widget build(BuildContext context) {

    final step = Provider.of<List<Brew>>(context);

    return ListView.builder(
      itemCount: step.length,
      itemBuilder: (context, index) {
        return BrewTile(brew: step[index]);
      },
    );
  }
}

这是 brew_tile.dart

import 'package:flutter_testing/models/brew.dart';
import 'package:flutter/material.dart';


 class  BrewTile extends StatelessWidget {

   final Brew brew;
   BrewTile({ this.brew });

   @override
   Widget build(BuildContext context) {
     return Padding(
       padding: const EdgeInsets.only(top: 8.0),
       child: Card(
         margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
         child: ListTile(
           leading: CircleAvatar(
             radius: 25.0,
             backgroundColor: Colors.brown[brew.stepCountValue],
           ),
         ),
       ),
     );

   }
 }

这是 brew.dart

class Brew {

  final int stepCountValue;

  Brew({ this.stepCountValue });

}

这是 pubspec.yaml

name: flutter_testing
description: A new Flutter application.

publish_to: 'none' 

version: 1.0.0+1

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: ^0.1.3
  font_awesome_flutter: ^8.4.0
  decimal: ^0.3.3
  image_picker_saver: ^0.3.0
  pedometer: ^0.0.5
  percent_indicator: ^1.0.14
  flutter_launcher_icons: ^0.7.0
  firebase_auth: ^0.16.0
  cloud_firestore: ^0.13.5
  provider: ^4.2.2+2
  flutter_spinkit: ^4.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter_icons:
  android: "launcher_icon"
  ios: true
  image_path: "assets/icon/step.png"

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true
  assets:
    - assets/images/

我希望这足以解决我的问题。我对 Flutter 很陌生,所以如果你能说出我必须在哪里改变什么,那就太好了。太感谢了!!!

标签: firebaseflutterdartgoogle-cloud-firestorereturn

解决方案


您应该像这样公开 brew 列表:

class NewApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
         StreamProvider<User>.value(value: AuthService().user),
         StreamProvider<List<Brew>>.value(value: DatabaseService().step),
      ],
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

打电话之前:

final step = Provider.of<List<Brew>>(context);

推荐阅读