如何将数据库作为构造函数参数传递给...类,并将其用作实例变量,而不是与Provider.of<数据库>



我想将数据写入fire存储数据库。

我在订阅类中这样写代码:

import 'package:flutter/material.dart';
import 'package:flutterapptest/services/database.dart';
import 'package:provider/provider.dart';
class Subscriptions extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Subscribed'),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _addTrack(context),
),
);
}
Future<void> _addTrack(BuildContext context) async {
final database = Provider.of<Database>(context, listen: false);
await database.addTrack({
'name': 'Track',
'time': 20,
});
}
}

在数据库类中。。。。。。

import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:meta/meta.dart';
abstract class Database {
Future<void> addTrack(Map<String, dynamic> trackData);
}
class FirestoreDatabase implements Database {
FirestoreDatabase({@required this.uid}) : assert(uid != null);
final String uid;
Future<void> addTrack(Map<String, dynamic> trackData) async{
final path = '/users/$uid/track/track_abc';
final documentReference = Firestore.instance.document(path);
await documentReference.setData(trackData);
}
}

为此,我得到了错误:

在订阅小部件上找不到正确的Provider<Database>

为此,一位朋友建议我做:

如果在路由内推送Subscriptions小部件,它将无法访问Provider.of<Database>.

最快的解决方案是将Database作为构造函数参数传递给Subscriptions类,并将其用作实例变量,而不是与Provider.of<Database>一起使用

有人能帮我现在该怎么办吗?我是新来的。

我就是这么做的。我知道这不仅仅包括addTrack函数,但我想你还需要一个全局状态somewhen和一个changeNotifier,否则使用提供程序毫无意义。

首先创建服务:

import 'package:cloud_firestore/cloud_firestore.dart';
final CollectionReference firestoreUsers =
Firestore.instance.collection('users');
class UserService {
static Future<Stream<Map<String, dynamic>>> streamTrack(String userId) async {
Stream<DocumentSnapshot> query =
await firestoreUsers.document('pathToListen...').snapshots();
return query.map((doc) => Map.from(doc.data));
}
static addTrack(String userId, Map<String, dynamic> trackData) async {
await firestoreUsers
.document(userId)
.collection('track')
.document('track_abc')
.setData(trackData);
}
}

然后是保持全局状态并使用changeNotificationer的提供程序。这些只是占位符。把你想听的东西放在数据库里。

import 'dart:async';
import 'package:flutter/material.dart';
import '../models_services/user_services.dart';
class UserProvider with ChangeNotifier {
// your global state, if you want to listen for data from database
StreamSubscription<Map<String, dynamic>> trackStream;
Map<String, dynamic> _streamedTrack;
Map<String, dynamic> get streamedTrack => _streamedTrack;
Future streamCurrentTrack(uid) async {
if(trackStream != null) {
trackStream.cancel();
}
Stream<Map<String, dynamic>> res = await UserService.streamTrack(uid);
trackStream = res.listen((track) {
_streamedTrack = track;
notifyListeners();
});
}
Future<void> addTrack(Map<String, dynamic> trackData) async {
// not sure what this is doing, i guess uid is null here...
FirestoreDatabase({@required this.uid}) : assert(uid != null);
final String uid;
await UserService.addTrack(uid, trackData);
}
}

在您的代码中使用带有changeNotifier的提供商:

import 'package:flutter/material.dart';
import 'package:flutterapptest/provider/user_provider.dart';
import 'package:provider/provider.dart';
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => UserProvider()),
...
],
child: MaterialApp(
home: Scaffold(body: Subscriptions()
)));
}
}
class Subscriptions extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Subscribed'),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => _addTrack(context),
),
);
}
Future<void> _addTrack(BuildContext context) async {
final database = Provider.of<UserProvider>(context, listen: false);
await database.addTrack({
'name': 'Track',
'time': 20,
});
}
}

相关内容

  • 没有找到相关文章

最新更新