You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Release APK部分内容不显示问题排查与修复求助

Flutter Debug正常但Release APK部分内容不显示的问题排查与修复

问题描述

开发的Flutter应用在Debug模式下运行一切正常,但构建Release APK后,界面中从Firebase Realtime Database加载的「Upcoming Launches」和「Planets and satellites」模块内容无法显示。相关核心代码如下:

import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get_space_ticket/Users_ui/buy_ticket_screen.dart';
import 'package:get_space_ticket/Users_ui/planet_screen.dart';
import 'package:get_space_ticket/Users_ui/view_all_ticket.dart';
import 'package:get_space_ticket/utils/planet_sat_view.dart';
import 'package:get_space_ticket/utils/ticket_view.dart';
import 'package:get_space_ticket/utils/app_styles.dart';
import 'package:get_space_ticket/utils/tracking_Screen.dart';

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool loading = false;
  DatabaseReference ref = FirebaseDatabase.instanceFor(
          app: Firebase.app(),
          databaseURL:
              'https://light-24555-default-rtdb.asia-southeast1.firebasedatabase.app')
      .ref("post");
  DatabaseReference ref2 = FirebaseDatabase.instanceFor(
          app: Firebase.app(),
          databaseURL:
              'https://light-24555-default-rtdb.asia-southeast1.firebasedatabase.app')
      .ref("Planet");
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Styles.bgColor,
        body: SingleChildScrollView(
          child: Column(
            children: [
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Column(
                  children: [
                    const Gap(40),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              "Good Morning",
                              style: Styles.headLineStyle3,
                            ),
                            const Gap(10),
                            SizedBox(
                              width: 300.0,
                              height: 70,
                              child: DefaultTextStyle(
                                style: const TextStyle(
                                    fontSize: 30,
                                    color: Colors.black87,
                                    fontWeight: FontWeight.bold),
                                child: AnimatedTextKit(
                                  totalRepeatCount: 2,
                                  animatedTexts: [
                                    TyperAnimatedText(
                                        'Travels with Speed of Light'),
                                  ],
                                ),
                              ),
                            ),
                          ],
                        ),
                        Container(
                          height: 50,
                          width: 50,
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(10),
                              image: const DecorationImage(
                                  fit: BoxFit.cover,
                                  image: AssetImage("assets/images/logo.jpg"))),
                        )
                      ],
                    ),
                    const Divider(
                      thickness: 2,
                      color: Colors.black54,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text('Now', style: Styles.textStyle2),
                            Text(
                              'Travelling',
                              style: Styles.textStyle2,
                            ),
                          ],
                        ),
                        Expanded(
                          child: SizedBox(
                            child: SingleChildScrollView(
                              scrollDirection: Axis.horizontal,
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.start,
                                children: [
                                  const Gap(5),
                                  InkWell(
                                    onTap: () {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  const TrackingScreen()));
                                    },
                                    child: const CircleAvatar(
                                      radius: 35,
                                      backgroundImage:
                                          AssetImage('assets/images/MARS.jpg'),
                                    ),
                                  ),
                                  const Gap(10),
                                  InkWell(
                                    onTap: () {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  const TrackingScreen()));
                                    },
                                    child: InkWell(
                                      onTap: () {
                                        Navigator.push(
                                            context,
                                            MaterialPageRoute(
                                                builder: (context) =>
                                                    const TrackingScreen()));
                                      },
                                      child: const CircleAvatar(
                                        radius: 35,
                                        backgroundImage: AssetImage(
                                            'assets/images/earth.jpg'),
                                      ),
                                    ),
                                  ),
                                  const Gap(10),
                                  InkWell(
                                    onTap: () {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  const TrackingScreen()));
                                    },
                                    child: const CircleAvatar(
                                      radius: 35,
                                      backgroundImage: AssetImage(
                                          'assets/images/firststation.jpg'),
                                    ),
                                  ),
                                  const Gap(10),
                                  InkWell(
                                    onTap: () {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  const TrackingScreen()));
                                    },
                                    child: const CircleAvatar(
                                      radius: 35,
                                      backgroundImage:
                                          AssetImage('assets/images/MARS.jpg'),
                                    ),
                                  ),
                                  const Gap(10),
                                  InkWell(
                                    onTap: () {
                                      Navigator.push(
                                          context,
                                          MaterialPageRoute(
                                              builder: (context) =>
                                                  const TrackingScreen()));
                                    },
                                    child: const CircleAvatar(
                                      radius: 35,
                                      backgroundImage:
                                          AssetImage('assets/images/earth.jpg'),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                    const Divider(
                      thickness: 2,
                      color: Colors.black54,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(
                          'Upcoming Launches',
                          style: Styles.headLineStyle2,
                        ),
                        InkWell(
                            onTap: () {
                              Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                      builder: (context) =>
                                          const ViewAllTicket()));
                            },
                            child: Text(
                              'View all',
                              style: TextStyle(
                                  color: Colors.brown.shade500,
                                  fontWeight: FontWeight.w400),
                            ))
                      ],
                    ),
                  ],
                ),
              ),
              Column(
                children: [
                  SingleChildScrollView(
                    child: SizedBox(
                      height: 200,
                      child: Expanded(
                        child: StreamBuilder(
                          stream: ref.onValue,
                          builder: (BuildContext context,
                              AsyncSnapshot<DatabaseEvent> snapshot) {
                            if (!snapshot.hasData) {
                              return const Center(
                                  child: CircularProgressIndicator());
                            } else {
                              Map<dynamic, dynamic>? map =
                                  snapshot.data?.snapshot.value as dynamic;
                              List<dynamic>? list = [];
                              list.clear();
                              list = map?.values.toList();
                              return SingleChildScrollView(
                                scrollDirection: Axis.horizontal,
                                child: Row(
                                  children: List.generate(3, (index) {
                                    if (list != null && list.length > index) {
                                      return InkWell(
                                        child: TicketView(
                                          photo: list[index]['image'] ??
                                              'N/A',
                                          formAdd:
                                              list[index]['fromAdd'] ?? 'N/A',
                                          toAdd: list[index]['toAdd'] ?? 'N/A',
                                          space:
                                              list[index]['spaceName'] ?? 'N/A',
                                          price: list[index]['price'] ?? 'N/A',
                                          launceDate: list[index]
                                                  ['launchingDate'] ??
                                              'N/A',
                                        ),
                                        onTap: () {
                                          Navigator.push(
                                            context,
                                            MaterialPageRoute(
                                              builder: (context) =>
                                                  BuyTicketScreen(
                                                launchingID: list?[index]
                                                    ['lunchCode'],
                                              ),
                                            ),
                                          );
                                        },
                                      );
                                    } else {
                                      return const SizedBox();
                                    }
                                  }),
                                ),
                              );
                            }
                          },
                        ),
                      ),
                    ),
                  ),
                ],
              ),
              const Gap(20),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    Text(
                      'Planets and satellites',
                      style: Styles.headLineStyle2,
                    ),
                  ],
                ),
              ),
              Column(
                children: [
                  SingleChildScrollView(
                    child: SizedBox(
                      height: 400,
                      child: FirebaseAnimatedList(
                        scrollDirection: Axis.horizontal,
                        query: ref2,
                        itemBuilder: (context, snapshot, animation, index) {
                          final imageUrl =
                              snapshot.child('image_url').value as String?;
                          final name = snapshot.child('name').value as String?;
                          final type = snapshot.child('type').value as String?;

                          if (imageUrl != null &&
                              name != null &&
                              type != null) {
                            return InkWell(
                              onTap: () {
                                Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) => PlanetScreen(
                                        name: snapshot
                                            .child('item')
                                            .value
                                            .toString()),
                                  ),
                                );
                              },
                              child: PlanetView(
                                photo: imageUrl,
                                name: name,
                                type: type,
                              ),
                            );
                          } else {
                            return const SizedBox();
                          }
                        },
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

可能的原因及修复方案

1. Firebase Realtime Database权限规则限制

Debug模式下可能使用了宽松的测试规则,Release模式下规则过于严格导致无法读取数据。

  • 修复:登录Firebase控制台,检查Realtime Database规则。临时测试可设置公开读取(上线前务必改回安全规则):
    {
      "rules": {
        ".read": true,
        ".write": "auth != null"
      }
    }
    
    正式环境建议使用基于认证用户的规则,确保只有合法用户能访问数据。

2. 代码混淆导致Firebase类被破坏

Flutter Release模式默认开启代码混淆,Firebase相关类被混淆后无法正常与服务端交互。

  • 修复:在android/app/proguard-rules.pro中添加以下混淆豁免规则:
    # Firebase Core
    -keep class com.google.firebase.** { *; }
    -keep class com.google.android.gms.** { *; }
    
    # Firebase Database
    -keep class com.google.firebase.database.** { *; }
    
    # 避免自定义数据模型类被混淆
    -keep class com.get_space_ticket.models.** { *; } # 替换为你的数据模型路径
    
    同时确保android/app/build.gradle中开启混淆并引用规则:
    buildTypes {
      release {
        minifyEnabled true
        useProguard true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
      }
    }
    

3. 缺少网络权限

Release APK可能未显式添加网络权限,导致无法连接Firebase服务。

  • 修复:在android/app/src/main/AndroidManifest.xml中添加网络权限:
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    

4. 数据解析的类型转换问题

Release模式下Dart类型检查更严格,强制类型转换可能失败导致数据无法加载。

  • 修复:优化类型转换逻辑,使用安全转换:
    将:
    Map<dynamic, dynamic>? map = snapshot.data?.snapshot.value as dynamic;
    
    修改为:
    Map<dynamic, dynamic>? map = snapshot.data?.snapshot.value as Map<dynamic, dynamic>?;
    
    同时确保所有子数据读取都做空安全判断,避免抛出异常。

内容的提问来源于stack exchange,提问作者Muntasir Ashif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:22:05