0

我正在尝试从firebase(用户集合-> uid 文档-> Summoner 信息集合-> id 文档-> 召唤者名称字段)中获取数据并显示召唤者名称的等级。以下是导致错误的屏幕:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:first_project/network/api.dart';
import 'package:first_project/screens/summoner_search.dart';
import 'package:flutter/material.dart';
import 'set_summoner_name.dart';

class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);

  static const id = '/mainScreen';
  @override
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  CollectionReference usersCollection =
      FirebaseFirestore.instance.collection('users');
  final FirebaseAuth _auth = FirebaseAuth.instance;
  late User loggedInUser;
  bool summonerExists = false;

  void getCurrentUser() {
    try {
      final user = _auth.currentUser;
      if (user != null) {
        loggedInUser = user;
        print(loggedInUser.email);
      }
    } catch (e) {
      print(e);
    }
    // here you write the codes to input the data into firestore
  }

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Main Screen'),
          actions: [
            IconButton(
              onPressed: () => Navigator.pushNamed(context, SummonerSearch.id),
              icon: Icon(Icons.search_off_rounded),
            ),
          ],
        ),
        body: Center(
          child: StreamBuilder(
            stream: usersCollection
                .doc(_auth.currentUser!.uid)
                .collection('Summoner Info')
                .snapshots(),
            builder:
                (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
              // checkIfSummonerExists(snapshot);
              if (!snapshot.hasData) {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
              print('Reached Here!');
              print(snapshot.data!.docs[0].data().toString());

              return ListView(
                children: snapshot.data!.docs.map((document) {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      ListTile(
                        title: Text('Name:' + document['summonerName']),
                      ),
                      Card(
                        child: FutureBuilder<dynamic>(
                          future: DataModel()
                              .getWholeRank(document['summonerName']),
                          builder: (context, snapshot) {
                            String tier;
                            String rank;
                            try {
                              //if successful, the player is ranked and has data
                              if (snapshot.hasData) {
                                tier = snapshot.data![0]['tier'];
                                rank = snapshot.data![0]['rank'];
                              } else {
                                return CircularProgressIndicator();
                              }
                              if (tier == 'CHALLENGER' || tier == 'MASTER') {
                                rank = '';
                              }
                              return Center(
                                child: Row(
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Text(tier),
                                    SizedBox(width: 2.0),
                                    Text(rank),
                                  ],
                                ),
                              );
                            } catch (e) {
                              //if unsuccessful call from api, means the player is unranked and json is empty
                              return Center(
                                child: Text('Unranked'),
                              );
                            }
                          },
                        ),
                      ),
                    ],
                  );
                }).toList(),
              );
            },
          ),
        ),
      ),
    );
  }
}

在上面的代码中,我注意到堆栈溢出错误从“卡”行开始大约 3/4 处,这是我从数据库中获取数据并从 API 获取数据的地方。如果我将所有这些注释掉并只显示召唤者名称,我不会收到任何错误。

作为参考的API函数,下面是getWholeRank方法的代码

Future<dynamic> fetchRank(String name) async {
    name = removeSpaces(name);
    String id = await fetchByName(name, 'id');
    NetworkHelper networkHelper = NetworkHelper(
        'https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/$id?api_key=$api_key');

    var rankData = await networkHelper.getRankData();
    return rankData;
  }

  Future<dynamic> getWholeRank(summonerName) async {
    var rankData = await rankObj.fetchRank(summonerName);
    return rankData;
  }

下面是我的 NetworkHelper 类:

import 'package:http/http.dart' as http;
import 'dart:convert';

class NetworkHelper {
  NetworkHelper(this.url);

  final String url;

  Future getData({String ch = 'default'}) async {
    http.Response response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      String data = response.body;

      // print(data);

      var decodedData = jsonDecode(data);

      if (ch == 'default') {
        print(decodedData);
        return decodedData; //returns map of data
      } else {
        //Options: id, accountID, name, puuid, profileIconID, revisionDate, summonerLevel,
        print(decodedData[ch]);
        return decodedData[ch];
      }
    } else {
      print('Status code: ');
      print(response
          .statusCode); //if doesn't work, it will print status code (200 is good, 400 etc. is bad)
    }
  }

  Future getRankData({String ch = 'default'}) async {
    http.Response response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      String data = response.body;

      var decodedData = jsonDecode(data);
      // print(decodedData[0]['tier']);
      return decodedData;
    } else {
      print('Failed! Status code: ');
      print(response
          .statusCode); //if doesn't work, it will print status code (200 is good, 400 etc. is bad)
    }
  }
}

如果有人可以帮助我理解为什么会出现堆栈溢出错误,将不胜感激!

4

1 回答 1

0

所以我修复了错误,这是因为我将一个对象传递给未来的参数,并且在堆栈跟踪中,有很多 DataModel 对象正在初始化,导致堆栈溢出。我通过将 DataModel 对象 rankObj 替换为“this”关键字,在 getWholeRank 方法中修复了它。

于 2021-07-17T21:04:35.137 回答