Flutter xmpp_plugin - App crashes when open the app again

47 Views Asked by At

When I login the app then clear the app from the background it occurs a problem and show me that "APPNAME keeps crashing". When i try it on my phone it doesn't happen just on some of phones and in emulators.

I tried detect the exact problem with firebase crashlytics but unfortunately i can't see anything. How can i fix the problem?

xmpp_service.dart

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:app/config.dart';
import 'package:app/services/rest.dart';
import 'package:app/view-models/command_controller.dart';
import 'package:xmpp_plugin/ennums/xmpp_connection_state.dart';
import 'package:xmpp_plugin/error_response_event.dart';
import 'package:xmpp_plugin/models/chat_state_model.dart';
import 'package:xmpp_plugin/models/connection_event.dart';
import 'package:xmpp_plugin/models/message_model.dart';
import 'package:xmpp_plugin/models/present_mode.dart';
import 'package:xmpp_plugin/success_response_event.dart';
import 'package:xmpp_plugin/xmpp_plugin.dart';

extension ConnectionStateToString on XmppConnectionState {
  String toConnectionName() {
    return toString().split('.').last;
  }
}

class XmppHelper implements DataChangeEvents {
  late XmppConnection flutterXmpp;
  late Timer timer;
  AppLifecycleState appLifecycleState = AppLifecycleState.resumed;
  bool isLogged = false;

  final CommandController _commandController = Get.find();

  String host = host;
  String appBotJid = BOT_JID;
  String connectionStatus = "disconnected";
  String userJid = "";
  String password = "";

  XmppHelper() {
    timer = Timer.periodic(const Duration(seconds: 10), (Timer t) async {
      if (connectionStatus == "authenticated" &&
          appLifecycleState == AppLifecycleState.resumed) {
        await ping();
      }
    });
  }

  Future<void> connect(String userJid, String password) async {
    final Map auth = {
      "user_jid":
          "$userJid/${Platform.isAndroid ? "Android" : "iOS"}${DateTime.now().millisecondsSinceEpoch}",
      "password": password,
      "host": host,
      "port": '5222',
      "requireSSLConnection": true,
      "autoDeliveryReceipt": true,
      "useStreamManagement": true,
      "automaticReconnection": true,
    };

    this.userJid = userJid;
    this.password = password;

    flutterXmpp = XmppConnection(auth);
    await flutterXmpp.start(_onError);
    await flutterXmpp.login();
  }

  void createRoster(String roster) {
    flutterXmpp.createRoster(roster);
  }

  void _onError(Object error) {}

  @override
  void onChatMessage(MessageChat messageChat) {}

  @override
  void onNormalMessage(MessageChat messageChat) {
    if (messageChat.body == "") {
      return;
    }
    _commandController.messageHandler(messageChat.body!);
  }

  @override
  void onChatStateChange(ChatState chatState) {}

  @override
  void onConnectionEvents(ConnectionEvent connectionEvent) {
    connectionStatus = connectionEvent.type!.toConnectionName();

    debugPrint("connStatus: $connectionStatus");

    if (connectionStatus == "authenticated") {
      isLogged = true;

     login();

    } else if (connectionStatus == "failed") {
    } else if (connectionStatus == "disconnected") {
    } else if (connectionStatus == "connected") {}
  }

  @override
  void onGroupMessage(MessageChat messageChat) {}

  @override
  void onPresenceChange(PresentModel message) {}

  @override
  void onSuccessEvent(SuccessResponseEvent successResponseEvent) {}

  @override
  void onXmppError(ErrorResponseEvent errorResponseEvent) {}

  void sendMessage(Map commandData) {
    int time = DateTime.now().millisecondsSinceEpoch;

    commandData["gonderen"] = userJid.toString().split("@")[0];

    debugPrint("commandData: $commandData");

    flutterXmpp.sendMessageWithType(
        appBotJid, jsonEncode(commandData), "$time", time);
  }

  Future<void> stop() async => await flutterXmpp.stop();

  Future<void> xmppLogout() async => await flutterXmpp.logout();

}

layout.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:app/view-models/command_controller.dart';
import 'package:app/widgets/side_menu.dart';
import 'package:xmpp_plugin/xmpp_plugin.dart';
import 'package:app/globals.dart' as globals;

class Layout extends StatefulWidget implements PreferredSizeWidget {
  const Layout({super.key});

  @override
  State<Layout> createState() => _LayoutState();

  @override
  Size get preferredSize => const Size.fromHeight(100);
}

class _LayoutState extends State<Layout> with WidgetsBindingObserver {
  final CommandController _controller = Get.put(CommandController());

  List pages = [
    PatientInfoPage(),
    const Page1(),
    const Page2(),
    const Page3(),
    const Page4(),
    const Page5(),
    const Page6(),
    const Page7()
  ];

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    XmppConnection.addListener(globals.xmppHelper);
    _controller.selectedPage.value = 7;
  }

  @override
  void dispose() {
    super.dispose();
    XmppConnection.removeListener(globals.xmppHelper);
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    super.didChangeAppLifecycleState(state);
    globals.xmppHelper.appLifecycleState = state;

    debugPrint("state: ${state.toString()}");

    if (state == AppLifecycleState.resumed) {
      debugPrint("state: resumed");
    } else if (state == AppLifecycleState.detached) {
      debugPrint("state: detached");
    }
  }

  @override
  Widget build(BuildContext context) {
    List<AppBar> appbars = [
      AppBar(title: Text(''.tr)),
      AppBar(),
      AppBar(),
      AppBar(title: Text(''.tr)),
      AppBar(title: Text(''.tr)),
      AppBar(),
      AppBar(title: Text(''.tr), actions: const [
        Padding(
            padding: EdgeInsets.only(right: 16.0),
            child: Icon(Icons.telegram, size: 50, color: Colors.blue)),
      ]),
      AppBar(
        automaticallyImplyLeading: false,
        title: const Text(''),
      )
    ];
    return PopScope(
      canPop: false,
      child: Scaffold(
        appBar: PreferredSize(
          preferredSize: const Size.fromHeight(50),
          child: Obx(() => appbars[_controller.selectedPage.value]),
        ),
        drawer: const SideNavigationMenu(),
        body: Obx(() => pages[_controller.selectedPage.value]),
      ),
    );
  }
}

Also the connection breaks when the app is background or no actions in 10 minutes.

I tried to handle it in many ways but i failed.

0

There are 0 best solutions below