You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中从Cloud Firestore删除文档:聊天APP消息撤回功能开发问题

Fixing the Message Unsend Feature in Your Flutter Chat App

Hey there! Let's get that message unsend functionality working for you. The key missing piece right now is passing the Firestore document ID to each message bubble so you can target the exact message to delete. Here's a step-by-step breakdown of how to adjust your code:

Step 1: Add Document ID to the Messagebubble Widget

First, update your Messagebubble stateful widget to accept and store the document ID of each message:

class Messagebubble extends StatefulWidget {
  const Messagebubble({
    required this.sender,
    required this.text,
    required this.isMe,
    required this.documentId, // New parameter for document ID
    super.key
  });

  final String sender;
  final String text;
  final bool isMe;
  final String documentId; // Store the document ID here

  @override
  State<Messagebubble> createState() => _MessagebubbleState();
}

Step 2: Pass the Document ID from MessagesStream

In the MessagesStream widget, when you create each Messagebubble, pass the Firestore document ID using message.id:

final messageBubble = Messagebubble(
  sender: messageSender,
  text: messageText,
  isMe: currentUser == messageSender,
  documentId: message.id, // Pass the document ID here
);

Step 3: Implement the Delete Logic in the Context Menu

Update the _showContextMenu method to use the document ID to delete the message from Firestore. We'll add error handling too, just in case:

void _showContextMenu(BuildContext context) async {
  final RenderObject? overlay = Overlay.of(context)?.context.findRenderObject();
  final result = await showMenu(
      context: context,
      position: RelativeRect.fromRect(
          Rect.fromLTWH(tapXY.dx, tapXY.dy, 30, 30),
          Rect.fromLTWH(0, 0, overlay!.paintBounds.size.width, overlay.paintBounds.size.height)),
      items: [
        const PopupMenuItem(
          value: 'unsend',
          child: Text('Unsend Message'),
        ),
      ]);

  switch (result) {
    case 'unsend':
      try {
        // Delete the message using the stored document ID
        await _fireStore.collection('messages').doc(widget.documentId).delete();
        debugPrint('Message unsent successfully!');
        // Optional: Show a success snackbar
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Message unsent')),
        );
      } catch (e) {
        debugPrint('Error unsending message: $e');
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Failed to unsend message')),
        );
      }
      break;
  }
}

Optional: Restrict Menu to Own Messages

Since you mentioned you'll handle checking if the message belongs to the current user, a nice UX touch is to only show the long-press menu for messages the user sent. Update the GestureDetector in Messagebubble's build method:

GestureDetector(
  onTapDown: (details) => _getTapPosition(details),
  // Only show menu if it's the user's own message
  onLongPress: widget.isMe ? () => _showContextMenu(context) : null,
  child: Material(...),
)

That's it! With these changes, when a user long-presses their own message and selects "Unsend Message", the corresponding document will be deleted from your Firestore messages collection.

内容的提问来源于stack exchange,提问作者Syed Abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 13:04:05