I have been trying to send SMS using telephony by following the youtube tutorial https://www.youtube.com/watch?v=X4yFdl3o1Lg. However, no message is being sent despite adding the required permissions.
final SmsSendStatusListener listener = (SendStatus status) {
// Handle the status
};
final Telephony telephony = Telephony.instance;
final _formKey = GlobalKey<FormState>();
_sendSMS2() async {
bool? permissionsGranted = await telephony.requestSmsPermissions;
print(permissionsGranted); //returns true
bool? canSendSms = await telephony.isSmsCapable;
print(canSendSms); //returns true
// Get sim state
SimState simState = await telephony.simState;
print(simState); //returns SimState.READY
telephony.sendSms(to: "123456", message: "hello", statusListener: listener);
}
}
The status returns sendStatus.SENT but I don't find any message being sent.
I really need help, please.
I removed the status listener and it then worked for me
telephony.sendSms(
to: "123123",
message: "May the force be with you! From MS",
// statusListener: smsListener
)
Try to change your phone number into international format. Then put await keyword for the method. This worked even i spam it many times.
onTap: () async {
final Telephony telephony = Telephony.instance;
if (await telephony.requestPhoneAndSmsPermissions) {
await telephony.sendSms(
to: '62xxxxxxxxxxx',
message: 'From flutter',
statusListener: (s) => print(s.name),
);
}
}
screenshot
Related
I need to verify by an ID that comes inside the data field that I received from a firebase message. How can I access this field based on the active notifications?
The point is to remove the notification once a page with that ID is opened.
This is what I have to get the notifications
page.dart
final List<ActiveNotification>? activeNotifications =
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()!
.getActiveNotifications();
that gives me the body, channelId, id, title and hascode.
While RemoteMessage message gives me a lot more stuff including a map data.
Is there a way to access this data field through the ActiveNotification?
I'm trying to do the verification with a sample on the body, but it's not a really good pratice giving the circumstances of the project.
What I receive from firebase is sent_at (date), service_id (the id I need to get to), id (other id but not so important), body, and title.
The service_id shouldn't be displayed in the notification tho, otherwise I'd get it through the notification body
Whoever answered and deleted their answer, helped my a lot. So I'm marking this as the solution because it worked. Thank you stranger.
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final Future<SharedPreferences> _savedNotifications =
SharedPreferences.getInstance();
_savedNotifications.then((saveNotifications) {
saveNotifications.setString(
"service_id_${message.messageId}", message.data["service_id"]);
});
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
onResumed();
break;
case AppLifecycleState.inactive:
onInactive();
break;
case AppLifecycleState.detached:
onDetached();
break;
case AppLifecycleState.paused:
onPaused();
break;
}
}
Future<String?> _getServiceId(title) async {
_savedNotifications.then((saveNotifications) => saveNotifications.reload());
return _savedNotifications.then((saveNotifications) {
_savedNotifications.then(
(value) => value.getKeys().forEach(
(element) async {
if (element.contains('service_id_')) {
String serviceId = value.get(element).toString();
}
},
),
);
});
}
void onResumed() async {
final prefs = await SharedPreferences.getInstance();
prefs.reload();
final List<ActiveNotification>? activeNotifications =
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()!
.getActiveNotifications();
for (ActiveNotification notification in activeNotifications!) {
String? serviceId = await _getServiceId(notification.title);
}
}
Im trying to implement the whatsapp like functionality of message being delivered when the receiver's app is in background state and the wifi is on.
I want to call the function to update the message document status from 'sent' to 'delivered'. But cant find where to call it from. I tried calling it inside FirebaseMessaging.onMessage.listen but it is still not working on background.
static setDeliveredStatus(
{required String senderId,
required String receiverId,
required String receiverName}) async {
print('setting = ${receiverName + receiverId}');
print('${currentUser!.displayName!} + ${senderId}');
QuerySnapshot query = await _firestore
.collection(CollectionKeys.messages)
.doc(receiverName + receiverId)
.collection(currentUser!.displayName! + senderId)
.where('status', isEqualTo: describeEnum(MessageStatus.sent))
.get();
query.docs.forEach((doc) async {
await doc.reference
.update({'status': describeEnum(MessageStatus.delivered)});
});
}
This above function is currently being called inside initState of my home.dart screen in a onMessage Listener:
FirebaseMessaging.onMessage.listen((message) {
if (message.notification != null) {
LocalNotificationService.createAndDisplayNotificationChannel(message);
FirebaseServices.setDeliveredStatus(
senderId: message.data['senderId'],
receiverId: message.data['receiverId'],
receiverName: message.data['receiverName']);
}
});
The FCM SDK has an onBackgroundMessage function where you can configure a callback function when receiving messages while the app is in the background.
FirebaseMessaging.onBackgroundMessage(_onBackgroundHandler);
See this document for reference. In the call back method you could put the logic to update the document.
I am coding a relatively simple app where one can set an emergency contact and in case of emergency, a text is sent to the contact by the touch of a remote button (connected via Bluetooth.) I have used the package contact picker and it works perfectly. Now, the issue is that I'm trying to save the contact locally for when the app is relaunched. The set state line returns an error that I cannot set contact to type string.
final ContactPicker _contactPicker = new ContactPicker();
Contact _contact;
#override
void initState() {
getData();
}
getData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_contact = prefs.getString(_contact.toString());
});
}```
maybe u need to decode that string from prefs so that it can get converted in Contact instance.
this line prefs.getString(_contact.toString()) is returning string in $fullName: $phoneNumber this format
e.g.
var decodedList = prefs.getString('contact').split(" ");
setState(() {
_contact = Contact(fullName: decodedList.first, phoneNumber: decodedList[1]);
});
I am able to implement voice and video call using agora.io library which is available at https://www.agora.io/ && https://github.com/AgoraIO/Flutter-SDK
how ever the process for starting a call is both user has to join a particular channel name defined by the user manually or automatically. which is not the practical way.
Is there any way to create a separate signalling system (may be using, nodejs socket, firebase or one-signal notification? )
What's the simultaneous/parallel way to be used along side that?
or what's the complete alternative?
Agora.io doesn't provide any method other passing a channel name manually or a default string. But what you can do is use Firebase dynamic link to share the channel name via a dynamic link. This link will redirect you to the page where you're taking channel name as input and fill the channel name according to the parameters passed. So your code will look something like:
class AgoraImpementation extends State<AgoraImplementation> {
#override
void initState() {
super.initState();
this.initDynamicLinks();
}
initDynamicLinks(BuildContext context) async {
await Future.delayed(Duration(seconds: 3));
var data = await FirebaseDynamicLinks.instance.getInitialLink();
var deepLink = data?.link;
final queryParams = deepLink.queryParameters;
if (queryParams.length > 0) {
var channelName = queryParams['channel_name'];
openFormScreen(channelName);
}
FirebaseDynamicLinks.instance.onLink(onSuccess: (dynamicLink)
async {
var deepLink = dynamicLink?.link;
final queryParams = deepLink.queryParameters;
if (queryParams.length > 0) {
var userName = queryParams['channel_name'];
openFormScreen(channelName);
}
debugPrint('DynamicLinks onLink $deepLink');
}, onError: (e) async {
debugPrint('DynamicLinks onError $e');
});
}
openFormScreen(String userName){
Navigator.of(context).pushNamed("routeFormScreen", arguments: {"channelName": channelName});
}
}
I have order which have 4 status : preparing , pending , delivering and delivered. and when the order status changed from one to another I wanted to show a notification to the user of the change occurs.
*I have used local notifications plugin. In order page widget shown here it is triggered by a stream above that get the order from fire-base.
*That's why I supposed that each time the status will change the orderPage will be rebuild again and initstate will be recalled and send the new notification msg with new status, but that didn't happen.
Another solution was to use didchangedependency but I got no different result.
This was a missed work I know, but this is what came to my mind.
*What I exactly want is something that make me listen on the status and when changes occur a function " singleNotification" will be called to show the notification.
any Help will be appreciated.
class OrderPage extends StatefulWidget {
const OrderPage({
Key key,
#required this.order,
}) : super(key: key);
final Order order;
#override
OrderPageState createState() {
return new OrderPageState();
}
}
class OrderPageState extends State<OrderPage> {
final DateTime now = DateTime.now().toUtc().add(
Duration(seconds: 3),
);
String title = "notification";
String msg = "";
FlutterLocalNotificationsPlugin localNotificationsPlugin =
FlutterLocalNotificationsPlugin();
initializeNotifications() async {
var initializeAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
var initializeIOS = IOSInitializationSettings();
var initSettings = InitializationSettings(initializeAndroid, initializeIOS);
await localNotificationsPlugin.initialize(initSettings);
}
Future singleNotification(
DateTime datetime, String message, String subtext, int hashcode,
{String sound}) async {
var androidChannel = AndroidNotificationDetails(
'channel-id',
'channel-name',
'channel-description',
importance: Importance.Max,
priority: Priority.Max,
);
var iosChannel = IOSNotificationDetails();
var platformChannel = NotificationDetails(androidChannel, iosChannel);
localNotificationsPlugin.schedule(
hashcode, message, subtext, datetime, platformChannel,
payload: hashcode.toString());
}
#override
void initState() {
super.initState();
getMsgState(widget.order.status);
initializeNotifications();
singleNotification(
now,
title,
msg,
98123871,
);
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
getMsgState(widget.order.status);
initializeNotifications();
singleNotification(
now,
title,
msg,
98123871,
);
}
Widget build(BuildContext context) {
return Container();
}
String getMsgState(String orderStatus) {
switch (orderStatus) {
case 'pending':
return msg = "Your order is pending";
break;
case 'preparing':
return msg = "your order is currently preparing";
break;
case 'delivering':
return msg = "your order is currently delivering";
break;
case 'delivered':
return msg = "Your order is delivered";
default:
return msg = "CustomStepState.Complete";
break;
}
}
If I understand correctly, Firebase knows when the order status is changed. And it sends a notification. And you would like to show it to the user.
You can use FCM and Firebase in-app notification. One of my project had a similar requirement whether server does the processing and the Flutter mobile app shows the status. I did the following :
Wrote a small code on the server side which calls Firebase cloud message API with user display message and data payload.
Wrote a code on Flutter mobile app side to display the notification (in the in-app style) if the app is already in the foreground.
Sample code snippet :
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
Helper.write('on message $message');
//Map data = json.decode(message);
this.scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message['aps']['alert']['body']),));
},
onResume: (Map<String, dynamic> message) async {
Helper.write('on resume $message');
},
onLaunch: (Map<String, dynamic> message) async {
Helper.write('on launch $message');
},
);
analytics.logEvent(name:'firebaseCloudMessaging_Listeners_Done',parameters:null);
}