ben-xD / push

Push notifications in Flutter without firebase_messaging.
https://pub.dev/packages/push
38 stars 23 forks source link

Got APNs Device Token even before the app launches #12

Open kukat opened 1 year ago

kukat commented 1 year ago

the APNs device token is printed even before the initState method.

debug console:

...
Xcode build done.                                           13.4s
(lldb) 2023-05-17 18:44:02.304860+0800 Runner[41331:40367550] [SceneConfiguration] Info.plist contained no UIScene configuration dictionary (looking for configuration named "(no name)")
Warning: Unable to create restoration in progress marker file
+APNs Device Token: 85a621db04b45694ea6c04b8ace5668cde4e9cb922ae9e4198dd432cbd95354b
Connecting to VM Service at ws://127.0.0.1:50044/wwXLk8SuYmo=/ws
+flutter: initState
...

and Push.instance.onNewToken.listen is never get executed.

main.dart:

class _MyHomePageState extends State<MyHomePage> {

  StreamSubscription<String>? onNewTokenSubscription;

  @override
  void initState() {
    print("initState");
    super.initState();

    onNewTokenSubscription = Push.instance.onNewToken.listen((token) {
-      print("Just got a new push notification registration token: ${token}");
    });
  }

  @override
  void dispose() {
    onNewTokenSubscription?.cancel();
    super.dispose();
  }

  void afterUserLogin() async {
    final isGranted = await Push.instance.requestPermission();
  }
...
kukat commented 1 year ago

still couldn't get onNewToken to work, workaround

final token = await Push.instance.token;
ben-xD commented 1 year ago

Hey @kukat, this probably happens because your app receives the APNs token before your that widget builds, and that time, listener in that widget hasn't been set up yet? You can either:

Push.instance.onNewToken.listen is useful to check if it has changed, so you can update your servers of the new token.

Let me know if that makes sense. Sorry for the late reply, I've been a bit busy 🙏

ben-xD commented 1 year ago

Ahh, @kukat I just looked at this again and found in the docs:

      // To be informed that the device's token has been updated by the operating system
      // You should update your servers with this token
      Push.instance.onNewToken.listen((token) {
        print("Just got a new FCM registration token: ${token}");
      });

This doesn't include the first one. Not very intuitive, but this means whenever that is called, you should call your backend APIs to update the token. Otherwise this function would be called everytime the app is started.

I thought of a couple of approaches:

1. Minimal calls to onNewToken:

Frequently call onNewToken. Whenever:

What do you think?

ben-xD commented 1 year ago

Turns out Android does approach 1, so I will use the same to be consistent.