Вот как бы я это сделал. Я знаю, что это включает в себя гораздо больше, чем просто функцию addTrack, но я думаю, что вам также когда-нибудь понадобится глобальное состояние и 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);
}
}
Затем провайдер, который содержит глобальное состояние и использует changeNotifier. Это просто заполнители. Поместите туда все, что вы хотите прослушать в базе данных.
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,
});
}
}