微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Flutter 中从 Firebase 抓取数据时出现堆栈溢出错误

如何解决在 Flutter 中从 Firebase 抓取数据时出现堆栈溢出错误

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

postman POST request
{
    "name":"al"
}

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

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

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(),);
            },);
  }
}

下面是我的 NetworkHelper 类:

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;
  }

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

解决方法

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。