Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firebase Messaging #3954

Closed
ir4ever opened this issue Oct 26, 2020 · 3 comments
Closed

Firebase Messaging #3954

ir4ever opened this issue Oct 26, 2020 · 3 comments
Labels
Needs Attention This issue needs maintainer attention.

Comments

@ir4ever
Copy link

ir4ever commented Oct 26, 2020

Segui o passo a passo para implementar mas o onBackgroundMessage causa o erro:
E/flutter ( 5481): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid argument(s): Failed to setup background message handler! `onBackgroundMessage`
E/flutter ( 5481):           should be a TOP-LEVEL OR STATIC FUNCTION and should NOT be tied to a
E/flutter ( 5481):           class or an anonymous function.

Sem usar ele recebo a notificação em segundo plano. OnMessage também não funciona.

Flutter doctor sem erros.

Versões usadas:

 classpath 'com.android.tools.build:gradle:3.3.3'
 classpath 'com.google.gms:google-services:4.3.4'

Pubspec:

 firebase_messaging: ^7.0.3

Meu myBackgroudHandler:

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
    Notificacao _notificacao = Notificacao();
    setState(() {
      controllerGet.contadorNotificacao.value++;
    });
    final prefs = await SharedPreferences.getInstance();
    await prefs.setInt('contadorNotificacao', controllerGet.contadorNotificacao.value);
   
    if (message.containsKey('data')) {
      // Handle data message
      final dynamic data = message['data'];
      _notificacao.urlImagem = data['image'];
      _notificacao.titulo = data['title'];
      _notificacao.texto = data['body'];
   
    }

    _salvarNotificacao(_notificacao);

  }

@override
  void initState() {
    super.initState();
    _pageController = PageController();
    _iniciarFirebase();
    initFCM();
  }

 Future initFCM() async{

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        SizeWidgets size = SizeWidgets();
        size = _verificaTela();
        final data = message['data'];
        showDialog(
            context: context,
            builder: (context){
              return AlertDialog(
                title: Text(data['title'], textAlign: TextAlign.center, style: TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                    color: temaPadrao.primaryColor
                ),),
                content: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Padding(
                      padding: EdgeInsets.only(bottom: 16.0),
                      child: Container(
                        child: data['image'] != null ?
                        Image.network(data['image'], height: size.heigth * .2, width: size.width * .8, fit: BoxFit.fill,)
                            : Image.asset('assets/images/logo.png', height: size.heigth * .2, fit: BoxFit.fill,),
                      ),
                    ),
                    Text(data['body'], textAlign: TextAlign.center,),
                  ],
                ),
                actions: <Widget>[
                  FlatButton(
                    onPressed: (){
                      Navigator.pop(context);
                    },
                    child: Text('Ok'),
                  )
                ],
              );
            }
        );
        myBackgroundMessageHandler(message);
        print("onMessage: $message");
      },
      onLaunch: (Map<String, dynamic> message) async {
        myBackgroundMessageHandler(message);
        print("onLaunch: $message");

      },
      onResume: (Map<String, dynamic> message) async {
        myBackgroundMessageHandler(message);
        print("onResume: $message");

      },
      onBackgroundMessage: myBackgroundMessageHandler
    );
    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(sound: true, badge: true, alert: true));
    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });
    _firebaseMessaging.getToken().then((String token) {
      assert(token != null);
      print("Push Messaging token: $token");
    });
  }
@TahaTesser
Copy link

Hi @Raphael-Jose-Ferraro-IRForever
You need to move myBackgroundMessageHandler out of any class and put it on the top or bottom. Do not put it inside any stateful or stateless .

Try this code sample

code sample
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}

final Map<String, Item> _items = <String, Item>{};
Item _itemForMessage(Map<String, dynamic> message) {
  final dynamic data = message['data'] ?? message;
  final String itemId = data['id'];
  final Item item = _items.putIfAbsent(itemId, () => Item(itemId: itemId))
    ..status = data['status'];
  return item;
}

class Item {
  Item({this.itemId});
  final String itemId;

  StreamController<Item> _controller = StreamController<Item>.broadcast();
  Stream<Item> get onChanged => _controller.stream;

  String _status;
  String get status => _status;
  set status(String value) {
    _status = value;
    _controller.add(this);
  }

  static final Map<String, Route<void>> routes = <String, Route<void>>{};
  Route<void> get route {
    final String routeName = '/detail/$itemId';
    return routes.putIfAbsent(
      routeName,
      () => MaterialPageRoute<void>(
        settings: RouteSettings(name: routeName),
        builder: (BuildContext context) => DetailPage(itemId),
      ),
    );
  }
}

class DetailPage extends StatefulWidget {
  DetailPage(this.itemId);
  final String itemId;
  @override
  _DetailPageState createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {
  Item _item;
  StreamSubscription<Item> _subscription;

  @override
  void initState() {
    super.initState();
    _item = _items[widget.itemId];
    _subscription = _item.onChanged.listen((Item item) {
      if (!mounted) {
        _subscription.cancel();
      } else {
        setState(() {
          _item = item;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Item ${_item.itemId}"),
      ),
      body: Material(
        child: Center(child: Text("Item status: ${_item.status}")),
      ),
    );
  }
}

class PushMessagingExample extends StatefulWidget {
  @override
  _PushMessagingExampleState createState() => _PushMessagingExampleState();
}

class _PushMessagingExampleState extends State<PushMessagingExample> {
  String _homeScreenText = "Waiting for token...";
  bool _topicButtonsDisabled = false;

  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  final TextEditingController _topicController =
      TextEditingController(text: 'topic');

  Widget _buildDialog(BuildContext context, Item item) {
    return AlertDialog(
      content: Text("Item ${item.itemId} has been updated"),
      actions: <Widget>[
        FlatButton(
          child: const Text('CLOSE'),
          onPressed: () {
            Navigator.pop(context, false);
          },
        ),
        FlatButton(
          child: const Text('SHOW'),
          onPressed: () {
            Navigator.pop(context, true);
          },
        ),
      ],
    );
  }

  void _showItemDialog(Map<String, dynamic> message) {
    showDialog<bool>(
      context: context,
      builder: (_) => _buildDialog(context, _itemForMessage(message)),
    ).then((bool shouldNavigate) {
      if (shouldNavigate == true) {
        _navigateToItemDetail(message);
      }
    });
  }

  void _navigateToItemDetail(Map<String, dynamic> message) {
    final Item item = _itemForMessage(message);
    // Clear away dialogs
    Navigator.popUntil(context, (Route<dynamic> route) => route is PageRoute);
    if (!item.route.isCurrent) {
      Navigator.push(context, item.route);
    }
  }

  @override
  void initState() {
    super.initState();
    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        _showItemDialog(message);
      },
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        _navigateToItemDetail(message);
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        _navigateToItemDetail(message);
      },
    );
    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(
            sound: true, badge: true, alert: true, provisional: true));
    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("Settings registered: $settings");
    });
    _firebaseMessaging.getToken().then((String token) {
      assert(token != null);
      setState(() {
        _homeScreenText = "Push Messaging token: $token";
      });
      print(_homeScreenText);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Push Messaging Demo'),
        ),
        // For testing -- simulate a message being received
        floatingActionButton: FloatingActionButton(
          onPressed: () => _showItemDialog(<String, dynamic>{
            "data": <String, String>{
              "id": "2",
              "status": "out of stock",
            },
          }),
          tooltip: 'Simulate Message',
          child: const Icon(Icons.message),
        ),
        body: Material(
          child: Column(
            children: <Widget>[
              Center(
                child: Text(_homeScreenText),
              ),
              Row(children: <Widget>[
                Expanded(
                  child: TextField(
                      controller: _topicController,
                      onChanged: (String v) {
                        setState(() {
                          _topicButtonsDisabled = v.isEmpty;
                        });
                      }),
                ),
                FlatButton(
                  child: const Text("subscribe"),
                  onPressed: _topicButtonsDisabled
                      ? null
                      : () {
                          _firebaseMessaging
                              .subscribeToTopic(_topicController.text);
                          _clearTopicText();
                        },
                ),
                FlatButton(
                  child: const Text("unsubscribe"),
                  onPressed: _topicButtonsDisabled
                      ? null
                      : () {
                          _firebaseMessaging
                              .unsubscribeFromTopic(_topicController.text);
                          _clearTopicText();
                        },
                ),
              ])
            ],
          ),
        ));
  }

  void _clearTopicText() {
    setState(() {
      _topicController.text = "";
      _topicButtonsDisabled = true;
    });
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  FirebaseApp app = await Firebase.initializeApp();
  assert(app != null);
  runApp(
    MaterialApp(
      home: PushMessagingExample(),
    ),
  );
}

@TahaTesser TahaTesser added the blocked: customer-response Waiting for customer response, e.g. more information was requested. label Oct 27, 2020
@google-oss-bot google-oss-bot added Needs Attention This issue needs maintainer attention. and removed blocked: customer-response Waiting for customer response, e.g. more information was requested. labels Oct 28, 2020
@ir4ever
Copy link
Author

ir4ever commented Oct 28, 2020

#1754

Resolved! Thanks for help!

@TahaTesser
Copy link

Hi @Raphael-Jose-Ferraro-IRForever
Given your last message I feel safe to close this issue, if you disagree please write in the comments and I will reopen it.
Thank you

@firebase firebase locked and limited conversation to collaborators Nov 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Needs Attention This issue needs maintainer attention.
Projects
None yet
Development

No branches or pull requests

3 participants