I am doing an app in flutter and I try to update for services the information that the user already introduced before (edit) . Right now when I rename it appears that is successfuly edited but the information still not change, I used cloud functions for this but still not working, even if I receive a message that it worked.
this is my index.js
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const admin = require("firebase-admin");
const serviceAccount = require("./serviceAccountKey.json");
const functions = require("firebase-functions");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL:
"https://animo-f15e0-default-rtdb.europe-west1.firebasedatabase.app",
});
exports.sendChatNotification = onDocumentCreated(
{
document: "notifications/{notificationId}",
cpu: 2,
},
async (event) => {
const snap = event.data;
const notification = snap.data();
const message = {
token: notification.token,
notification: {
title: notification.title,
body: notification.body,
},
data: notification.data,
apns: {
headers: {
"apns-push-type": "alert",
},
payload: {
aps: {
sound: "default",
},
},
},
};
try {
const response = await admin.messaging().send(message);
console.log("Successfully sent notification:", response);
await snap.ref.delete();
return {success: true};
} catch (error) {
console.error("Error sending notification:", error);
return {error};
}
},
);
exports.addChatMessage = functions.https.onCall(async (request) => {
try {
const {message, sender, name, chatRoomId, rid} = request.data;
console.log("Received data:");
console.log("message: ", request.data.message);
console.log("sender: ", request.data.sender);
console.log("time: ", request.data.time);
console.log("type: ", request.data.type);
console.log("unread: ", request.data.unread);
console.log("name: ", request.data.name);
console.log("chatRoomId: ", request.data.chatRoomId);
console.log("rid: ", request.data.rid);
const batch = admin.firestore().batch();
const messageColl = admin.firestore().collection("ChatRoom");
batch.set(messageColl.doc(chatRoomId).collection("chats").doc(), {
"sender": sender,
"time": admin.firestore.FieldValue.serverTimestamp(),
"type": "text",
"message": message,
"unread": true,
"name": name,
});
const recipientDoc = await admin.firestore().collection("Users")
.doc(rid).get();
const recipientToken = recipientDoc.data() ? recipientDoc.data()
.fcmToken : null;
if (recipientToken) {
batch.set(admin.firestore().collection("notifications").doc(), {
"token": recipientToken,
"title": name,
"body": message,
"data": {"chatRoomId": chatRoomId, "type": "chat_message"},
"timestamp": admin.firestore.FieldValue.serverTimestamp(),
});
}
await batch.commit();
return {success: true};
} catch (error) {
console.error("Error adding chat message: ", error);
return {success: false, error: error.message};
}
});
exports.updateUserData = functions.https.onCall(async (request) => {
try {
const {
uid,
data,
business,
social,
service,
product,
review,
booking,
order,
addingNewService,
addingNewProduct,
addingNewReview,
addingNewBooking,
placingNewOrder,
} = request.data;
console.log("User id: ", uid);
const userDoc = admin.firestore().collection("Users").doc(uid);
if (data) {
await userDoc.update(data);
}
if (business) {
console.log("Business data: ", business);
await userDoc
.collection("BusinessAccount")
.doc("detail")
.set(business, {merge: true});
}
if (social) {
console.log("Social data: ", social);
await userDoc
.collection("Social")
.doc("detail")
.set(social, {merge: true});
}
if (service) {
console.log("Service data: ", service);
if (addingNewService === true) {
service.createdAt = admin.firestore.FieldValue.serverTimestamp();
await userDoc.collection("Services").add(service);
} else if (service.serviceId) {
const serviceId = service.serviceId;
service.updatedAt = admin.firestore.FieldValue.serverTimestamp();
delete service.serviceId;
await userDoc
.collection("Services")
.doc(serviceId)
.update(service);
}
}
if (booking && addingNewBooking === true) {
booking.createdAt = admin.firestore.FieldValue.serverTimestamp();
console.log("Booking data: ", booking);
await admin.firestore()
.collection("ChatRoom")
.doc(booking.chatRoomId)
.collection("chats")
.doc(booking.docId)
.set({
...booking,
time: admin.firestore.FieldValue.serverTimestamp(),
});
await admin.firestore()
.collection("Users")
.doc(booking.sender)
.collection("Bookings")
.add({
...booking,
createdAt: admin.firestore.FieldValue.serverTimestamp(),
});
await admin.firestore()
.collection("Users")
.doc(booking.serviceProviderId)
.collection("Bookings")
.add({
...booking,
createdAt: admin.firestore.FieldValue.serverTimestamp(),
});
}
if (product && addingNewProduct === true) {
product.createdAt = admin.firestore.FieldValue.serverTimestamp();
console.log("Product data: ", product);
await userDoc.collection("Products").add(product);
}
if (review && addingNewReview === true) {
review.timestamp = admin.firestore.FieldValue.serverTimestamp();
console.log("Review data: ", review);
const reviewRef = admin.firestore()
.collection("Users")
.doc(review.serviceProviderId)
.collection("BusinessAccount")
.doc("detail")
.collection("reviews");
await reviewRef.add(review);
}
if (order && placingNewOrder === true) {
order.createdAt = admin.firestore.FieldValue.serverTimestamp();
console.log("Order data: ", order);
const orderId = admin.firestore().collection("orders").doc().id;
order.orderId = orderId;
await admin.firestore()
.collection("Users")
.doc(order.sellerId)
.collection("Orders")
.doc(orderId)
.set({
...order,
createdAt: admin.firestore.FieldValue.serverTimestamp(),
});
await admin.firestore()
.collection("Users")
.doc(order.buyerId)
.collection("Orders")
.doc(orderId)
.set({
...order,
createdAt: admin.firestore.FieldValue.serverTimestamp(),
});
const sellerDoc = await admin.firestore()
.collection("Users")
.doc(order.sellerId)
.get();
const sellerData = sellerDoc.data();
const sellerToken = sellerData ? sellerData.fcmToken : null;
if (sellerToken) {
await admin.firestore().collection("notifications").add({
token: sellerToken,
title: "New Order",
body: `New order received for ${order.productName}`,
data: {
type: "new_order",
orderId: orderId,
productId: order.productId,
},
timestamp: admin.firestore.FieldValue.serverTimestamp(),
});
}
return {success: true, orderId: orderId};
}
return {success: true};
} catch (error) {
console.error("Error updating user data: ", error);
return {success: false, error: error.message};
}
});
exports.onNewBookingRequest = onDocumentCreated(
{
document: "notifications/{notificationId}",
cpu: 2,
},
async (event) => {
const snap = event.data;
const notification = snap.data();
if (notification.type !== "booking_request") {
return;
}
try {
// Get recipient's FCM token
const recipientDoc = await admin.firestore()
.collection("Users")
.doc(notification.recipientId)
.get();
const recipientData = recipientDoc.data();
const recipientToken = recipientData ? recipientData.fcmToken : null;
if (!recipientToken) {
console.log("No FCM token found for recipient");
return;
}
// Send FCM notification
await admin.messaging().send({
token: recipientToken,
notification: {
title: notification.title,
body: notification.body,
},
data: {
chatRoomId: notification.data.chatRoomId,
bookingId: notification.data.bookingId,
click_action: "FLUTTER_NOTIFICATION_CLICK",
},
});
console.log("Notification sent successfully");
// Clean up the notification document after sending
await snap.ref.delete();
} catch (error) {
console.error("Error sending notification:", error);
}
},
);
exports.onNewOrder = onDocumentCreated(
{
document: "notifications/{notificationId}",
cpu: 2,
},
async (event) => {
const snap = event.data;
const notification = snap.data();
if (notification.type !== "new_order") {
return;
}
try {
// Get recipient's FCM token
const recipientDoc = await admin.firestore()
.collection("Users")
.doc(notification.recipientId)
.get();
const recipientData = recipientDoc.data();
const recipientToken = recipientData ? recipientData.fcmToken : null;
if (!recipientToken) {
console.log("No FCM token found for recipient");
return;
}
// Send FCM notification
await admin.messaging().send({
token: recipientToken,
notification: {
title: notification.title,
body: notification.body,
},
data: {
orderId: notification.data.orderId,
productId: notification.data.productId,
type: "new_order",
click_action: "FLUTTER_NOTIFICATION_CLICK",
},
});
console.log("Order notification sent successfully");
// Clean up the notification document after sending
await snap.ref.delete();
} catch (error) {
console.error("Error sending order notification:", error);
}
},
);
and
void _editService(BuildContext context, String serviceId, Map<String, dynamic> currentData) {
// Initialize controllers with current data
final TextEditingController nameController = TextEditingController(text: currentData['name']);
final TextEditingController descriptionController = TextEditingController(text: currentData['description']);
final TextEditingController priceController = TextEditingController(text: currentData['price'].toString());
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
builder: (BuildContext bottomSheetContext) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
left: 16,
right: 16,
top: 16,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: nameController,
decoration: const InputDecoration(
labelText: "Service Name",
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: descriptionController,
decoration: const InputDecoration(
labelText: "Description",
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextField(
controller: priceController,
decoration: const InputDecoration(
labelText: "Price",
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.attach_money),
),
keyboardType: TextInputType.number,
),
const SizedBox(height: 24),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: darkBlueColor,
foregroundColor: Colors.white,
minimumSize: const Size(double.infinity, 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
onPressed: () async {
try {
showDialog(
context: bottomSheetContext,
barrierDismissible: false,
builder: (BuildContext dialogContext) {
return const Center(child: CircularProgressIndicator());
},
);
AppCloudFunctionService appCloudFunctionService = AppCloudFunctionService();
final result = await appCloudFunctionService.updateUserData({
'uid': userId,
'service': {
'serviceId': serviceId,
'name': nameController.text.trim(),
'description': descriptionController.text.trim(),
'price': double.parse(priceController.text),
'photoUrl': currentData['photoUrl'],
},
});
if (!result) {
throw Exception('Failed to update service');
}
if (bottomSheetContext.mounted) {
Navigator.pop(bottomSheetContext); // Close loading dialog
Navigator.pop(bottomSheetContext); // Close bottom sheet
}
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Service updated successfully'),
backgroundColor: Colors.green,
),
);
}
} catch (e) {
print('Error updating service: $e');
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error updating service: $e'),
backgroundColor: Colors.red,
),
);
}
}
},
child: const Text(
'Save Changes',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
),
],
),
);
},
);
}
void _deleteService(String serviceId) async {
try {
// Show confirmation dialog
bool confirmDelete = await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Delete Service'),
content: const Text('Are you sure you want to delete this service?'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: const Text(
'Delete',
style: TextStyle(color: Colors.red),
),
),
],
);
},
);
if (confirmDelete == true) {
AppCloudFunctionService appCloudFunctionService = AppCloudFunctionService();
final result = await appCloudFunctionService.updateUserData({
'uid': userId,
'service': {
'serviceId': serviceId,
'delete': true,
},
});
if (!result) {
throw Exception('Failed to delete service');
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Service deleted successfully'),
backgroundColor: Colors.green,
),
);
}
} catch (error) {
print('Failed to delete service: $error');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error deleting service: $error'),
backgroundColor: Colors.red,
),
);
}
}