问题描述
我是使用Firebase函数的新手,我已经设置了环境并部署了可以正常工作的其他函数,但是,我想知道如何实现一个允许用户在有人开始关注它们时收到通知的函数(在添加新ID时会通知该关注者的收藏集。)
这是一个数据库,当用户(A)跟随用户(B)时,该数据库将获得一个ID,任何用户都有自己的ID,因此当用户跟随另一个用户时,该用户(A)的ID将保存到用户(B)id({ _buildUserProfile() {
double height = responsive.height(context);
double width = responsive.width(context);
String comment = widget.reviews.comments;
int reviews = _posts.length;
int followersNew = _followerCount;
int likeCount = widget.reviews.likeCount;
int point = reviews * 10;
int point2 = followersNew * 30;
int point3 = likeCount * 20;
int totalPoints = point + point2 + point3;
return Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
decoration: Boxdecoration(
color: Colors.blueGrey[300],BoxShadow: shadowList,image: decorationImage(
image: NetworkImage(widget.imageUrl),fit: BoxFit.cover,),height: height / 2,width: width,child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
SizedBox(
height: height / 50,SizedBox(
height: height / 50,],SizedBox(
height: height / 130,_productimage(),MessageFollowUnfollowEditButton(
followOrUnfollow: _followOrUnfollow,isFollowing: _isFollowing,user: widget.user,reviewId: widget.authorId,imageUrl: widget.userImage,reviews: widget.reviews,currentUserId: widget.currentUserId,isTrue: widget.isTrue == true ? true : false,Padding(
padding: EdgeInsets.fromLTRB(width / 22,5.0,width / 22,0.0),child: Row(
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Container(
decoration: Boxdecoration(
borderRadius: BorderRadius.circular(
responsive.width(context) / 42),gradient: LinearGradient(
colors: [
Colors.white,Colors.white,//aqui
child: Padding(
padding: EdgeInsets.all(width / 22),child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[
Column(
children: <Widget>[
Text(
_posts.length.toString(),style: TextStyle(
fontSize: width / 22,fontWeight: FontWeight.w600,Text(
'Opiniones',style: kjosefin,Column(
children: <Widget>[
Text(
_followerCount.toString(),Text(
'Seguidores',Column(
children: <Widget>[
Row(
children: <Widget>[
Icon(
Icons.control_point,size: width / 20,color: Colors.orangeAccent,Text(
totalPoints.toString(),style: TextStyle(
fontSize: width / 22,Text(
'Puntaje',style:
kjosefin.copyWith(fontSize: height / 70),Column(
children: <Widget>[
Row(
children: <Widget>[
Icon(
Icons.favorite,color: Colors.redAccent,Text(
'${widget.reviews.likeCount.toString()}',Text(
'Likes',SizedBox(
height: height / 130,Container(
width: width / 1.1,height: height / 8,decoration: Boxdecoration(
BoxShadow: shadowList,color: Colors.white,borderRadius: BorderRadius.all(
Radius.circular(height / 70),child: Center(
child: Padding(
padding: EdgeInsets.all(height / 70),child: Text(
'"$comment"',overflow: TextOverflow.ellipsis,textAlign: TextAlign.center,maxLines: 9,style: kjosefin.copyWith(color: Colors.grey),)
],);
}
)。因此,我需要一个将通知发送给用户(B)的函数,以获得新的关注者。
请参见下面的结构
class FollowerNotification extends StatefulWidget {
static final String id = 'chat_list';
final String currentUserId;
final String peerId;
final User user;
FollowerNotification({Key key,this.currentUserId,this.peerId,this.user})
: super(key: key);
@override
State createState() =>
FollowerNotificationState(currentUserId: currentUserId);
}
class FollowerNotificationState extends State<FollowerNotification> {
FollowerNotificationState({Key key,@required this.currentUserId});
final String currentUserId;
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final FlutterlocalnotificationsPlugin FlutterlocalnotificationsPlugin =
FlutterlocalnotificationsPlugin();
final GoogleSignIn googleSignIn = GoogleSignIn();
bool isLoading = false;
@override
void initState() {
super.initState();
registerNotification();
configlocalnotification();
}
void registerNotification() {
firebaseMessaging.requestNotificationPermissions();
firebaseMessaging.configure(
onMessage: (Map<String,dynamic> message) {
print('onMessage: $message');
Platform.isAndroid
? showNotification(message['notification'])
: showNotification(message['aps']['alert']);
return;
},onResume: (Map<String,dynamic> message) {
print('onResume: $message');
return;
},onLaunch: (Map<String,dynamic> message) {
print('onLaunch: $message');
return;
},);
firebaseMessaging.getToken().then(
(token) {
print('token: $token');
Firestore.instance
.collection('users')
.document(widget.currentUserId)
.updateData({'pushToken': token});
},).catchError(
(err) {
Fluttertoast.showToast(msg: err.message.toString());
},);
}
void configlocalnotification() {
var initializationSettingsAndroid =
new AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = new IOSInitializationSettings();
var initializationSettings = new InitializationSettings(
initializationSettingsAndroid,initializationSettingsIOS);
FlutterlocalnotificationsPlugin.initialize(initializationSettings);
}
void showNotification(message) async {
var androidplatformChannelSpecifics = new AndroidNotificationDetails(
Platform.isAndroid
? 'com.dfa.Flutterchatdemo'
: 'com.duytq.Flutterchatdemo','Flutter chat demo','your channel description',playSound: true,enableVibration: true,importance: Importance.Max,priority: Priority.High,);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
androidplatformChannelSpecifics,iOSPlatformChannelSpecifics);
print(message);
print(message['body'].toString());
print(json.encode(message));
await FlutterlocalnotificationsPlugin.show(0,message['title'].toString(),message['body'].toString(),platformChannelSpecifics,payload: json.encode(message));
await FlutterlocalnotificationsPlugin.show(
0,'plain title','plain body',payload: 'item x');
}
const functions = require('firebase-functions');
const admin = require('firebase-admin')
admin.initializeApp()
exports.sendNotification = functions.firestore
.document('messages/{groupId1}/{groupId2}/{message}')
.onCreate((snap,context) => {
console.log('----------------start function--------------------')
const doc = snap.data()
console.log(doc)
const idFrom = doc.idFrom
const idTo = doc.idTo
const contentMessage = doc.content
// Get push token user to (receive)
admin
.firestore()
.collection('users')
.where('id','==',idTo)
.get()
.then(querySnapshot => {
querySnapshot.forEach(userTo => {
console.log(`Found user to: ${userTo.data().nickname}`)
if (userTo.data().pushToken && userTo.data().chattingWith !== idFrom) {
// Get info user from (sent)
admin
.firestore()
.collection('users')
.where('id',idFrom)
.get()
.then(querySnapshot2 => {
querySnapshot2.forEach(userFrom => {
console.log(`Found user from: ${userFrom.data().nickname}`)
const payload = {
notification: {
title: `You have a message from "${userFrom.data().nickname}"`,body: contentMessage,badge: '1',sound: 'default'
}
}
// Let push to the target device
admin
.messaging()
.sendToDevice(userTo.data().pushToken,payload)
.then(response => {
console.log('Successfully sent message:',response)
})
.catch(error => {
console.log('Error sending message:',error)
})
})
})
} else {
console.log('Can not find pushToken target user')
}
})
})
return null
})
我在index.js中拥有的代码
{{1}}
解决方法
所有异步工作完成后,您需要终止Cloud Function,请参见doc。对于后台触发的Cloud Function(例如Cloud Firestore函数onCreate
触发器),您必须返回异步方法调用返回的承诺链。
在您的情况下,不仅您不退回get()
返回的承诺,而且末尾还有一个return null;
,这可能表明Cloud Function平台可以清理您的功能在异步工作完成之前。
以下方法可以解决这个问题(未经测试)。请注意,我假设仅存在一个与where('id','==',idTo)
相对应的文档,以及仅一个与where('id',idFrom)
相对应的文档。
exports.sendNotification = functions.firestore
.document('messages/{groupId1}/{groupId2}/{message}')
.onCreate((snap,context) => {
const doc = snap.data()
console.log(doc)
const idFrom = doc.idFrom
const idTo = doc.idTo
const contentMessage = doc.content
// Get push token user to (receive)
return admin
.firestore()
.collection('users')
.where('id',idTo)
.get()
.then(querySnapshot => {
const userTo = querySnapshot.docs[0];
console.log(`Found user to: ${userTo.data().nickname}`)
if (userTo.data().pushToken && userTo.data().chattingWith !== idFrom) {
// Get info user from (sent)
return admin
.firestore()
.collection('users')
.where('id',idFrom)
.get();
} else {
console.log('Can not find pushToken target user')
throw new Error('Can not find pushToken target user');
}
})
.then(querySnapshot => {
const userFrom = querySnapshot.docs[0];
console.log(`Found user from: ${userFrom.data().nickname}`)
const payload = {
notification: {
title: `You have a message from "${userFrom.data().nickname}"`,body: contentMessage,badge: '1',sound: 'default'
}
}
// Let push to the target device
return admin
.messaging()
.sendToDevice(userTo.data().pushToken,payload);
})
.then(response => {
console.log('Successfully sent message:',response);
return null;
})
.catch(error => {
console.log('Error sending message:',error);
return null;
});
});