Flutter应用iOS端FCM推送异常求助:仅前台可接收通知,后台/终止状态报aps-environment权限错误
Hey there, let's work through this iOS FCM notification issue—since it's working perfectly on Android but failing when the app is in background or terminated, the core problem is tied to iOS-specific APNs entitlements and configuration. Let's break down the fixes step by step:
1. Fix the "aps-environment" Entitlement Missing Error
This is the root cause of your issue, as explicitly stated in the error log. Here's how to resolve it:
- Check Xcode Capabilities: Open your Flutter project in Xcode, go to your target's Signing & Capabilities tab. Ensure the Push Notifications capability is added and enabled (you should see a checkmark next to it).
- Verify Provisioning Profile: Make sure your active Provisioning Profile includes the Push Notifications entitlement. If you're using manual signing, regenerate the profile in the Apple Developer Portal to include this permission. For automatic signing, toggle the Push Notifications capability off and on again to trigger a profile refresh.
- Inspect Entitlements File: Look for the
Runner.entitlementsfile in your iOS project. It should contain this entry:
If it's missing, add it manually. Ensure the string matches your build environment (development for debug, production for release).<key>aps-environment</key> <string>development</string> <!-- Use "production" for release builds -->
2. Validate FCM Message Structure
iOS treats notification payloads differently depending on the app state:
- Use Notification-Type Payloads: For background/terminated state, FCM must send a payload that includes the
notificationkey (not justdata). A valid payload example:
Data-only payloads won't trigger notifications when the app is in background/terminated—they require the app to be active.{ "notification": { "title": "Your Title", "body": "Your Message" }, "data": { "key": "value" }, "to": "DEVICE_TOKEN" } - Check FCM Console Settings: When testing from the Firebase Console, ensure you've selected "Notification" instead of "Data" under the "Message type" dropdown, and that iOS-specific settings (like sound, badge) are configured.
3. Address Splash Screen & Bloc Integration
Your use of a Splash Screen and Bloc might be delaying Firebase initialization:
- Initialize Firebase Early: Make sure Firebase is initialized before your app runs. Update your
main.dartto:
If your Splash Screen loads before Firebase is ready, FCM might fail to register properly for background notifications.void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // Critical for early FCM setup runApp(const MyApp()); } - Isolate Bloc Impact: Temporarily comment out the
_navigateToItemDetailcalls inonLaunchandonResumeto see if the callbacks fire at all. If they do, the issue might be with your Bloc state not being ready when navigation triggers—you can adjust to wait for Bloc initialization before navigating.
4. Resolve Network Resolver Timeouts
The nw_resolver errors you're seeing are likely a side effect of the entitlement issue. Once you fix the aps-environment problem, these timeouts should disappear. If they persist:
- Check if your device can access
iid.googleapis.comandapp-measurement.com(try opening them in Safari). - Switch between Wi-Fi and cellular data to rule out network-specific issues.
- Ensure your device isn't using a VPN or proxy that blocks Google services.
5. Final Checks
- Verify Device Notification Permissions: Go to your iOS device's Settings > [Your App] > Notifications and confirm all notification permissions are enabled (including Lock Screen, Notification Center, etc.).
- Match Build Environments: If you're testing with a development build, ensure your FCM messages are sent to the development APNs server (Firebase handles this automatically if you use the correct profile).
- Clean & Rebuild: Sometimes old build artifacts cause issues. Run
flutter clean, delete the app from your device, then rebuild and reinstall.
Once you work through these steps, your background/terminated notifications should start working as expected!
内容的提问来源于stack exchange,提问作者Mariam Younes

