#firebase #flutter #google-cloud-firestore #google-cloud-functions #android-notifications
#firebase #трепетание #google-cloud-firestore #google-cloud-функции #android-уведомления
Вопрос:
ОТРЕДАКТИРОВАНА функция onMessageSent. Все та же ошибка.
Я пытаюсь включить push-уведомления в flutter и использую Firebase Messaging. Я сталкиваюсь со следующей проблемой. Их два, а именно «onCreateActivityFeedItem» и «onMessageSent». Для первого, «onCreateActivityFeedItem», функция уведомления работает отлично, но я не смог распознать проблему со вторым. Пожалуйста, помогите.
Проблема, с которой я сталкиваюсь :
onMessageSent
TypeError: Cannot read property 'androidNotificationToken' of undefined at exports.onMessageSent.functions.firestore.document.onCreate (/workspace/index.js:152:47) at process._tickCallback (internal/process/next_tick.js:68:7)
Вот «onCreateActivityFeedItem» . :
Из моего index.js
exports.onCreateActivityFeedItem = functions.firestore
.document("/feed/{userId}/feedItems/{activityFeedItem}")
.onCreate(async (snapshot, context) => {
console.log("Activity Feed Item Created", snapshot.data());
// 1) Get user connected to the feed
const userId = context.params.userId;
const mediaUrl=context.params.mediaUrl;
const userRef = admin.firestore().doc(`users/${userId}`);
const doc = await userRef.get();
// 2) Once we have user, check if they have a notification token; send notification, if they have a token
const androidNotificationToken = doc.data().androidNotificationToken;
const createdActivityFeedItem = snapshot.data();
if (androidNotificationToken) {
sendNotification(androidNotificationToken, createdActivityFeedItem);
} else {
console.log("No token for user, cannot send notification");
}
function sendNotification(androidNotificationToken, activityFeedItem) {
let body;
// 3) switch body value based off of notification type
switch (activityFeedItem.type) {
case "comment":
body = `${activityFeedItem.username} replied: ${
activityFeedItem.commentData
}.`;
break;
case "like":
body = `${activityFeedItem.username} booped you.`;
break;
case "follow":
body = `${activityFeedItem.username} started petting you.`;
break;
default:
break;
}
// 4) Create message for push notification
const message = {
notification: {
body:body,
image:mediaUrl
},
token: androidNotificationToken,
data: {recipient: userId,
}
};
// 5) Send message with admin.messaging()
admin
.messaging()
.send(message)
.then(response => {
// Response is a message ID string
console.log("Successfully sent message", response);
return null;
})
.catch(error => {
console.log("Successfully sent message", response);
throw Error("Could not send message.",error)});
// admin.messaging().sendToDevice(androidNotificationToken,message);
}
});
Из моего index.js
Вот, «onMessageSent»:
exports.onMessageSent = functions.firestore
.document('/messages/{chatId}/messageInfo/{messageFeedItem}')
.onCreate(async (snapshot, context) => {
console.log("Message Created", snapshot.data());
// 1) Get user connected to the feed
const chatId=context.params.chatId;
const userId = context.params.idTo;
const idTo =context.params.idTo;
const userRef = admin.firestore().doc(`users/${idTo}`);
const doc = await userRef.get();
const createdMessageFeedItem = snapshot.data();
// 2) Once we have user, check if they have a notification token; send notification, if they have a token
const androidNotificationToken = doc.data().androidNotificationToken;
if (androidNotificationToken) {
sendNotification(androidNotificationToken, createdMessageFeedItem);
} else {
console.log("No token for user, cannot send notification");
}
function sendNotification(androidNotificationToken,createdMessageFeedItem) {
let body;
// 3) switch body value based off of notification type
switch (messageFeedItem.type) {
case 0:
body = `${messageFeedItem.username} has sent a message : ${
messageFeedItem.content
}.`;
break;
case 1:
body = `${messageFeedItem.username} has sent an image.`;
break;
case 2:
body = `${messageFeedItem.username} has sent a gif.`;
break;
default:
break;
}
// 4) Create message for push notification
const message = {
notification:
{body:body,},
token: androidNotificationToken,
data: {recipient: idTo,}
};
// 5) Send message with admin.messaging()
admin
.messaging()
.send(androidNotificationToken,message)
.then(response => {
// Response is a message ID string
console.log("Successfully sent message", response);
return null;
})
.catch(error => {
console.log("Successfully sent message", response);
throw Error("Could not send message.",error)});
// admin.messaging().sendToDevice(androidNotificationToken,message);
}
});
Где я вызвал / объявил onMessage, onResume :
configurePushNotifications() {
final GoogleSignInAccount user = googleSignIn.currentUser;
if (Platform.isIOS) {
getiOSPermission();
}
_firebaseMessaging.getToken().then((token) {
print("Firebase messaging token : $token");
setState(() {
currentUser.androidNotificationToken = token;
});
usersref.doc(user.id).update({"androidNotificationToken": token});
});
_firebaseMessaging.configure(
onLaunch: (Map<String, dynamic> message) async {
_firebaseMessaging.getToken().then((token) {
print("Firebase messaging token : $token");
usersref.doc(user.id).update({"androidNotificationToken": token});
});
// print("On Launch : $messagen");
// _navigateToDetail(message);
},
onResume: (Map<String, dynamic> message) async {
_firebaseMessaging.getToken().then((token) {
print("Firebase messaging token : $token");
usersref.doc(user.id).update({"androidNotificationToken": token});
});
print("On Resume : $message");
_navigateToDetail(message);
},
onMessage: (Map<String, dynamic> message) async {
print("On message : $messagen");
final String recipientId = message['data']['recipient'];
final String body = message['notification']['body'];
if (recipientId == user.id) {
//Notification shown");
SnackBar snackBar = SnackBar(
backgroundColor: Colors.blueAccent,
content: Text(
body,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
action: SnackBarAction(
label: "Go",
textColor: Colors.black,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ActivityFeed();
}),
);
}),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
//Notifications not shown.");
},
);
}
Я пробовал разные способы, такие как получение androidNotificationToken путем обновления в cloud firestore и получения его, но это не сработало.
[Пользователи в облачном Firestore][1]
[1] https://imgur.com/a/u5Df0zD
Я просто новичок, пытаюсь изучать новые вещи. Пожалуйста, помогите. Спасибо, SLN
Комментарии:
1. При переполнении стека не показывайте изображения текста и кода. Скопируйте только соответствующий код в вопрос и отформатируйте его так, чтобы его было легко читать, копировать и искать.
2. Спасибо, г-н Дуг Стивенсон
Ответ №1:
Cannot read type error of undefined
ошибка возникает, когда в docu.data().androidNotificationToken
Убедитесь, что ссылка правильная, я предпочитаю использовать этот тип пути для большей ясности let ref = db.collection(‘users’).doc(userID);
и т. Д
Вы также можете получить пустой снимок
var snapshot = await ref.get();
if(snapshot.empty){
console.log(‘snapshot is empty’);
}
Комментарии:
1. Ошибка: значение для аргумента «documentPath» не является допустимым путем к ресурсу. Путь должен быть непустой строкой. . Попробовал: пусть ref = admin.firestore().collection(
users
).doc(userId); const userRef = admin.firestore().doc(users/${userId}
); Что может пойти не так..2. Эта новая ошибка, которую вы получаете, возникает, когда значение в ссылке равно null