这是一个简化的情况:在我的appPage 中,我将profilePage 和dashboardPage 作为页面的主体,并且它们位于索引堆栈中。 这个appPage有一个底部导航栏来控制渲染哪个主体。
假设 profilePage 和dashboardPage 两个主体都具有完全相同的代码,并且正在使用streamBuilder 监听相同的流。 我正在使用提供程序从 firestore 访问我的数据流。
我的问题是只有一个页面可以正确访问数据。 另一个只会显示加载图标,这是在连接状态等待时发生的。 如果我完全删除其中一个页面上的streamBuilder代码并将其替换为空白页面,那么该应用程序将按预期工作。 问题是当尝试在多个页面上使用 StreamBuilder 时。
似乎同一个流不能在不同页面上的 2 个不同的 StreamBuilder 中使用,但我不明白为什么它不起作用,因为我试图将我的流与提供者集中在一起。
我经常使用人工智能来尝试解决这个问题,但无济于事。 我是一名 16 岁的孩子,正在尝试学习编码,非常感谢任何帮助!
这是我的不同页面的代码: 主要:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:provider/provider.dart';
import 'Services/ProviderClass.dart';
import 'pages/landing_page.dart';
import 'pages/login_page.dart';
import 'pages/signup_page.dart';
import 'pages/app_page.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform,);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<FirestoreService>(
create: (_) => FirestoreService(),
)
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/AppPage',
onGenerateRoute: (settings){
if (FirebaseAuth.instance.currentUser == null && settings.name != '/LoginPage' && settings.name != '/SignupPage'&& settings.name!='/LandingPage') {
return MaterialPageRoute(builder: (context) => LandingPage());
}
switch (settings.name) {
case '/LandingPage':
return MaterialPageRoute(builder: (context) => LandingPage());
case '/LoginPage':
return MaterialPageRoute(builder: (context) => LoginPage());
case '/SignupPage':
return MaterialPageRoute(builder: (context) => SignupPage());
case '/AppPage':
return MaterialPageRoute(builder: (context) => AppPage());
default:
return MaterialPageRoute(builder: (context) => LoginPage());
}
},
),
);
}
}
应用程序页面代码(底部导航栏包含正文的页面)
import 'package:flutter/material.dart';
import 'AppPages/profile_page.dart';
import 'AppPages/dashboard_page.dart';
class AppPage extends StatefulWidget {
const AppPage({super.key});
@override
State<AppPage> createState() => _AppPageState();
}
class _AppPageState extends State<AppPage> {
int selectedIndex=1;
void navigateToIndex(int index){
setState(() {
selectedIndex=index;
});
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green.shade200,
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.dashboard),
label: "Dashboard"
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle_sharp),
label: "Profile"
)
],
currentIndex: selectedIndex,
onTap: navigateToIndex,
fixedColor: Colors.black,
backgroundColor: Colors.green.shade50,
type: BottomNavigationBarType.fixed,
),
body: IndexedStack(
index: selectedIndex,
children: [
DashboardPage(),
ProfilePage(),
],
),
);
}
}
仪表板页面
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:provider/provider.dart';
import '../../Services/ProviderClass.dart';
class DashboardPage extends StatefulWidget {
const DashboardPage({super.key});
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
late FirestoreService firestoreService;
@override
void initState() {
super.initState();
firestoreService = Provider.of<FirestoreService>(context, listen: false);
}
// This widget is the root of your application
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
return SingleChildScrollView(
child: Center(
child: Column(
children: [
SizedBox(height:screenSize.height*0.01,),
Text(
'Your Nutrition History',
style: TextStyle(
color: Colors.black,
fontSize: 14+screenSize.width*0.03
),
),
SizedBox(height:screenSize.height*0.025,),
StreamBuilder<DocumentSnapshot>(
stream: firestoreService.userStream,
builder: (context, snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
if (!snapshot.hasData || !snapshot.data!.exists) {
return Center(child: Text('No data available'));
}
//process user data here and return widget based on it
}
),
SizedBox(height: screenSize.height*0.05,),
],
),
),
);
}
}
个人资料页面
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../Services/ProviderClass.dart';
class ProfilePage extends StatefulWidget {
const ProfilePage({super.key});
@override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
// This widget is the root of your application.
late FirestoreService firestoreService;
@override
void initState() {
super.initState();
firestoreService = Provider.of<FirestoreService>(context, listen: false);
}
@override
Widget build(BuildContext context) {
var screenSize = MediaQuery.of(context).size;
var aspectRatio = screenSize.width/screenSize.height;
return Center(
child: SingleChildScrollView(
child: Column(
children: [
Text(
"Profile",
style: TextStyle(
color: Colors.black,
fontSize: 14+ screenSize.width*0.01
),
),
StreamBuilder<DocumentSnapshot>(
stream: firestoreService.userStream,
builder: (context, snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
if (!snapshot.hasData || !snapshot.data!.exists) {
return Center(child: Text('No data available'));
}
//process user data here and return widget
}
),
],
),
),
);
}
}
提供者类
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
class FirestoreService {
final String userUid = FirebaseAuth.instance.currentUser!.uid;
Stream<DocumentSnapshot> get userStream {
return FirebaseFirestore.instance.collection('users').doc(userUid).snapshots();
}
}
我在同一页面上尝试了 2 个相同的流构建器并且有效,这也让我感到困惑。 当我做 2 个相同的流构建器时,每页一个,只有一个有效。
唯一需要更改的是提供程序类。 使用流控制器可以将单个流广播给许多听众。
这里应该是新的 Firestore 提供程序代码,其他任何内容都不需要更改
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
class FirestoreService {
final String userUid = FirebaseAuth.instance.currentUser!.uid;
final StreamController<DocumentSnapshot> userController = StreamController<DocumentSnapshot>.broadcast();
FirestoreService() {
FirebaseFirestore.instance.collection('users').doc(userUid).snapshots().listen((snapshot) {
userController.add(snapshot);
});
}