Closed soyangel closed 3 years ago
Thanks for reporting I can reproduce this behavior on the example app. Will investigate the issue today
Fixed in version 3.1.1.
which is now available on pub.dev
I have checked and it connects right but now I'm having a problem with subscriptions to characteristics not being called.
As before if I comment the FirebaseMessaging.onBackgroundMessage
I can receive data from a characteristic correctly.
I have a small example for our custom BLE hardware, I guess you should be able to reproduce with something similar.
(Let me know If you prefer this as a separate issue)
pubspec.yaml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_reactive_ble: ^3.1.1
permission_handler: ^7.1.0
firebase_core: "^1.2.0"
firebase_messaging: "^10.0.0"
pinenacl: ^0.2.0
msgpack_dart: ^1.0.0
main.dart
import 'dart:typed_data';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:msgpack_dart/msgpack_dart.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pinenacl/tweetnacl.dart';
var myServiceUUID = Uuid.parse('00dac273-80b3-475c-83fc-56540d498c68');
var myCharUUID = Uuid.parse('01dac273-80b3-475c-83fc-56540d498c68');
final flutterReactiveBle = FlutterReactiveBle();
FirebaseMessaging messaging = FirebaseMessaging.instance;
QualifiedCharacteristic? characteristic;
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
Permission.location.request();
_initFirebase();
}
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print("Handling a background message: ${message.messageId}");
}
void _initFirebase() async {
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Map<String, DiscoveredDevice> _devicesNear = {};
@override
void initState() {
super.initState();
_startBleScan();
}
void _startBleScan() {
flutterReactiveBle.scanForDevices(
withServices: [],
requireLocationServicesEnabled: true,
scanMode: ScanMode.lowLatency,
).listen((device) {
if (!_devicesNear.containsKey(device.id)) {
setState(() {
_devicesNear[device.id] = device;
});
}
}, onError: (err) {
print('error scanning: $err');
});
}
void _connectToDevice(String deviceId) async {
flutterReactiveBle
.connectToDevice(
id: deviceId,
connectionTimeout: Duration(seconds: 5),
)
.listen((ConnectionStateUpdate st) async {
print('connection state update: $st');
if (st.connectionState == DeviceConnectionState.connected) {
print('writing data to device');
if (characteristic == null) {
var services = await flutterReactiveBle.discoverServices(deviceId);
print('services: $services');
for (var service in services) {
print('service: $service');
if (service.serviceId == myServiceUUID) {
for (var char in service.characteristicIds) {
if (char == myCharUUID) {
characteristic = QualifiedCharacteristic(
serviceId: myServiceUUID,
characteristicId: myCharUUID,
deviceId: deviceId,
);
flutterReactiveBle
.subscribeToCharacteristic(characteristic!)
.listen((data) {
print('received data=$data');
});
break;
}
}
}
}
}
print('before writing data');
await flutterReactiveBle
.writeCharacteristicWithoutResponse(characteristic!, value: [3]);
print('after writing data');
var sk = Uint8List(TweetNaCl.secretKeyLength);
var pk = Uint8List(TweetNaCl.publicKeyLength);
TweetNaCl.crypto_box_keypair(pk, sk);
var msg = serialize({'t': 'l2', 'pk': pk});
var txBuf = List<int>.from(msg);
while (txBuf.isNotEmpty) {
var chunkLength = txBuf.length;
if (chunkLength > 20) {
chunkLength = 20;
}
var chunk = txBuf.sublist(0, chunkLength);
print('before write chunk');
await flutterReactiveBle.writeCharacteristicWithoutResponse(
characteristic!,
value: chunk);
print('chunk written');
txBuf.removeRange(0, chunkLength);
}
}
});
}
Widget _buildItem(BuildContext context, int index) {
var device = _devicesNear.values.elementAt(index);
return InkWell(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(
child: Text(
'${device.id}: ${device.name}',
style: TextStyle(fontSize: 18),
),
),
),
onTap: () {
_connectToDevice(device.id);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BLE example'),
),
body: Center(
child: ListView.builder(
itemBuilder: (context, index) => _buildItem(context, index),
itemCount: _devicesNear.length,
),
),
);
}
}
hmm thought I fixed everything hopefully I have some time tomorrow
before I publish a new version can you test on branch fix-read-subscribe-background-issues
? I did test it myself and it should work now
Of course, tomorrow will try it on our app.
Thanks!
Seems ok on our app.
Thanks again guys! 👏👏👏
fix is available in version 3.1.1+1
Describe the bug Cannot connect to BLE device when using Firebase Messaging on Android and setting a background message handler.
To Reproduce Steps to reproduce the behavior:
FirebaseMessaging.onBackgroundMessage
it connects successfullyExpected behavior Should connect successfully to BLE device
Smartphone / tablet
Peripheral device
Additional context pubspec.yaml
main.dart