Thông báo tới nơi. Lúc thì ứng dụng hiển thị nó, lúc thì hệ điều hành, lúc chạm vào thì mở đúng màn hình còn lúc lại quăng người dùng ra trang chủ. Hành vi trông như ngẫu nhiên cho tới khi bạn nhìn ra cấu trúc bên dưới: cùng một tin nhắn đi theo bốn đường khác nhau tuỳ theo lúc đó ứng dụng đang làm gì. Trạng thái ứng dụng Ai hiển thị Handler nào chạy Chạy nổi Mặc định là không ai onMessage Chạy nền Hệ điều hành onBackgroundMessage (isolate riêng) Đã tắt hẳn Hệ điều hành onBackgroundMessage (isolate riêng) Được mở bằng cách chạm — onMessageOpenedApp , hoặc getInitialMessage nếu trước đó đã tắt hẳn Mọi lỗi thông báo tôi từng gỡ đều là một trong các dòng đó chưa được xử lý. Nối đủ bốn dòng thì phần lớn sự bí ẩn biến mất. Notification message so với data message Trước khi vào mã, đây là phân biệt quyết định mọi thứ: một payload FCM có thể chứa khối notification , khối data , hoặc cả hai. Có notification — hệ điều hành tự hiển thị khi ứng dụng chạy nề...
Property Editor exposes editable fields for the selected widget in DevTools. Bài này chuyển quan sát đó thành một mô hình nhỏ để bạn có thể kiểm thử, đo lường và giữ cho code dễ bảo trì khi app lớn lên. Vấn đề cốt lõi Edit properties live from DevTools while iterating on a screen. Câu hỏi hữu ích không phải API hay pattern có đẹp riêng lẻ hay không, mà là state nằm ở đâu, boundary nào chịu trách nhiệm khi lỗi xảy ra, và người dùng phục hồi thế nào khi happy path biến mất. Mô hình thực tế Faster than hot-reload cycles when tuning padding, colors, and flags. Hãy bắt đầu bằng một owner rõ ràng cho behavior. Widget chỉ nên render và phát intent; IO, persistence, permission và retry nên nằm sau một interface nhỏ. Nhờ vậy bạn có seam để fake trong test và một chỗ ghi lại các dữ kiện cần theo dõi ở production. Trong app Flutter, boundary thường có dạng: Widget phát intent như load, submit, refresh hoặc retry. Controller hoặc use case validate intent rồi gọi boundary. Boundary trả v...