UPDATE:
Ok so from all the comments I got convinced that using Firebase is the best solution for a number of reasons but how would I check for that change (canceled == yes) in my json file from firebase and automatically send the notification if the course is canceled.
Sample JSON response:
{
"class" : "Class",
"time" : "00:00",
"trainer" : "T",
"canceled" : ""
},
{
"class" : "Class",
"time" : "00:00",
"trainer" : "T",
"canceled" : ""
}
INITIAL QUESTION
I am parsing a json api and one of the fields is called canceled.
I would like my app to set a notification whenever that canceled key has a value of yes and so far it's easy, just create a simple notification like in the android developer topic and if canceled == yes update the Builder and then notify();.
The issue here is how can I keep checking for changes in the json after the app has been closed and set the notification ?
I have access to the server and make changes to the api if required.
Can I do this without the help of any third party services?
As #Sujal mentioned With Android O you have restriction on running background service for a long time. So It's better move this thing to server side. Whenever there is a change in the status i.e. Whenever key canceled becomes yes send a notification to android device which would show the Notification.
Ref : https://firebase.google.com/docs/cloud-messaging/
Ref : https://www.codementor.io/flame3/send-push-notifications-to-android-with-firebase-du10860kb
Related
I'm doing my final year project about flood push notification. Previously, a user will retrieve notifications whenever the value in database changes from 0 to 1. But right now,in my app, the user can choose which places he parks his car and he can retrieved status and notification based on the park's place whether it's zero or one. As for example, User A set his spinner value in Mid Valley and User B set his spinner value in KPS. User A will get notification when FLOOD_STATUS_MID_VALLEY is 1, while User B didn't receive any notifications because FLOOD_STATUS_KPS is still 0. Anyone can help me on how to send notification based on the spinner value in the app?
Screenshot of my app
Screenshot
below is the python code that running on server to send notification based on a value called "FLOOD_STATUS" in firebase database
from pusher_push_notifications import PushNotifications
config = {
'apiKey': "APIKEY",
'authDomain': "car-app-push-notification.firebaseapp.com",
'databaseURL': "https://car-app-push-notification.firebaseio.com",
'projectId': "car-app-push-notification",
'storageBucket': "car-app-push-notification.appspot.com",
'messagingSenderId': "596729642105",
'appId': "APPID",
'measurementId': "G-9LMJGS1BDW"
}
firebase = pyrebase.initialize_app(config)
db = firebase.database()
beams_client = PushNotifications(
instance_id='49f62b05-bd81-4040-ab57-80afa56a8680',
secret_key='SECRET KEY',
)
def stream_handler(message):
print(message)
if(message['data'] is 1):
response = beams_client.publish_to_interests(
interests=['hello'],
publish_body={
'apns': {
'aps': {
'alert': 'Hello!',
},
},
'fcm': {
'notification': {
'title': 'Alert!',
'body': 'It is starting to flood, please remove your car immediately!',
},
},
},
)
print(response['publishId'])
my_stream = db.child("FLOOD_STATUS").stream(stream_handler,None)
As this is your FYP, I won't provide any code for this.
When a user changes where they parked, you will want to change their device interest to match the relevant location.
When the FLOOD_STATUS is updated to 1 for a given location, you send the notification to the matching interest.
I suggest that, when the user A select the MID_VALLEY in the Spinner you send the selected value to the server. I recommend you to have a look on this tutorial to see how to get the selected value from Spinner
At server side, when the FLOOD_STATUS_MID_VALLEY is 1 you only send the notification to the user A(because you knew the FCM token of the user A).
If you want to custom the item of Spinner you can watch this tutorial.
I'm currently building a logic app in Azure to send text messages with Twilio. Everything is working smoothly except that I can't send complex URL in the body.
For exemple if I send this : https://example.com?id=26 I will recieve the the correct string, but the parameter is not concatenated correctly with the domain in the clickable link.
So when I click the link in the text message it only opens the https://example.com . The message I'm sending is built like this :
"Send_Text_Message_(SMS)": {
"inputs": {
"body": {
"body": "#{triggerBody()?['message']}#{triggerBody()?['url']}#{body('Insert_row')?['Id']}",
"from": "xxx-xxx-xxxx",
"to": "#triggerBody()?['phone']"
},
message: Hello please click this link
url :https://example.com?id=
id: 26
so the final body would be like : [message][url][id]
I've tried sending a simple string like https://example.com?id=8 to see if it was the "complex" body concatenation that was failing, but it's still not working.
Can anyone help :) ?
For anyone that would be stuck with this here's how I tricked android :
I added a / after the .com so now the url I'm sending is :
https://example.com/?id=36
I´m creating this chat app using Firebase. I wanted to create a system
where every device having the chat app installed is responsible for delivering chat messages.
Even if the device did not send the message it plays a part in the pool of workers, that deliver chat messages.
Now for a normal chat app the device that creates the chat message can easily send the message using E.g. OneSignal.
In my case user can chat with abstract things and there can be many people listening for new chat messages. One is sending and 1000+ is listening.
Here is where the problem comes. If one device is responsible for notifying 1000+ other it can get really heavy on the load. I was thinking all other devices can help out with the delivery,
so I´m trying this Firebase database notification entry:
{
"NOTIFICATIONS" : {
"-Kg4_cnR9T8Efx77rL2n" : {
"targetId" : "-KfpVVenyQccKqAxxrvE",
"text1" : "There´s a message for you",
"text2" : "Pluto",
"text3" : "",
"time" : 1490447404504,
"type" : "chatMessage"
},
"-Kg4_eWQFZndhztPqSTp" : {
"targetId" : "-KfpWz7ZWBAa_8pLM7tI",
"text1" : "There´s a message for you",
"text2" : "Saturnus",
"text3" : "",
"time" : 1490447411536,
"type" : "chatMessage"
}
}
}
and when one device is creating a message it post this new NOTIFICATIONS that will be picked up by all devices that are listening.
Now since all devices is listening on the NOTIFICATIONS and will grab one NOTIFICATIONS and send the chat message heads up, to all other devices that are registered on the targetId the problem obviously arise.
Here are the TARGET_VISITORS. This are the users that are registers for new chat messages.
{
"TARGET_VISITORS" : {
"-KfpVVenyQccKqAxxrvE" : {
"HnhLyXRxUINmlltK3jdsfxx2QBYiQ53" : {
"notify" : true,
"time" : 1490300590623,
"userFirebaseId" : "HnhLyXRxUINmlltK3jdsfxx2QBYiQ53"
}
},
"-KfpWz7ZWBAa_8pLM7tI" : {
"HnhLrryXUINmlltK3jdsfxx2QBYi3455" : {
"notify" : true,
"time" : 1490300581677,
"userFirebaseId" : "HnhLrryXUINmlltK3jdsfxx2QBYi3455"
}
}
Can I use the Firebase Transaction for this?
Like one device pick up a NOTIFICATIONS and then gets maybe 10 TARGET_VISITORS (there can be 1000+), and in a Firebase transaction locking down TARGET_VISITORS to perform the chat message heads up delivery on his userFirebaseId or OneSignal PlayerId.?
After that the TARGET_VISITORS can save the NOTIFICATIONS id and by doing that prevent getting duplicate messages.
Maybe creating a visitor lock rule like:
"TARGET_VISITORS_LOCK": {
".read": "auth != null",
"$FirebaseId": {
// This need to be a final entity.
// we can write as long as old data or new data does not exist.
// In other words, we can write if we're deleting or creating data, but not updating data.
".write": "!data.exists() || !newData.exists() && auth != null"
}
},
And then run an Data Fan Out updateChildren on the TARGET_VISITORS_LOCK, if it fails it means some other device is running the updateChildren before me and sending the notification to the single device. What will happen her if device having an offline period?
Many devices in the pool of workers can have the same NOTIFICATIONS to try to send and they will fight over TARGET_VISITORS, so to speak
Then comes the problem to know when to remove a NOTIFICATIONS entry, remove it when all TARGET_VISITORS have been notified :) Yea this is quite fun :)
It´s all theoretical at this point and i´m reading a loot so hoping for some input about this?
I am first mobile application developing on Smartface App Studio. I have tho question.
1- I see this error: Access violation at address 00000000. Read of address 00000000 when add second Dataset. And does not run application on emulator or usb real phone until delete Dataset.
2- I read Local.Notifications guide but could not run notifications on phone screen. I saved dates to table but can not make them as reminder. Which page should i add the function block and how should i do this.
Thanks.
It seems a problem is occured when adding a Dataset. Did you try with a second project ? It seems working with the latest version of Smartface App Studio which downloadable via Account page.
Local Notifications are not added to the calendar/reminder. These are app specific notifications.
First off all, you should create a local notification.
For example;
var localNotification = new Notifications.LocalNotification({
id : id,
fireDate : new Date(),
alertTitle : "AlertTitle",
alertBody : "Alert Body",
smallIcon : "icon_notification_small.png",
launchImage : "icon_notification.png",
sound : "notifsound.mp3",
repeatInterval : Notifications.CalendarUnit.minute,
onReceivedNotification : function (e) {
alert("onReceived");
}
});
It creates a notification for you and it works at given date.
If you want to immaediately show the notification , you should run that code below;
Notifications.local.presentNotification(localNotification);
I found how to send push notification to Android device using Django here (here is the code).
So adopted that and my code looks like this:
def sendAndroidPushNotification(registration_id, collapse_key, a, b) :
try:
auth = getNewAndroidAuthorizationToken() # this works I'm fetching new token so this is up to date (its length is 267 characters)
push_request = urllib2.Request("https://android.apis.google.com/c2dm/send")
data = urllib.urlencode({'data.testA' : a,
'data.testB' : b,
'collapse_key' : collapse_key,
'registration_id': registration_id
})
push_request.add_data( data )
push_request.add_header('Authorization', 'GoogleLogin auth=' + auth)
push_request.add_header('Content-Type', 'application/x-www-form-urlencoded')
push_request.add_header('Content-Length', len(data))
urllib2.build_opener().open(push_request)
except urllib2.HTTPError as e:
print 'got exception during push notification'
print 'Reason: "{0}" code: {1}'.format(e.reason, e.code)
pass
this give me error: "Reason: "Unauthorized" code: 401" (at some point it was 403). Version which uses httplib.HTTPSConnection instead of urllib2.Request has same problem.
It looks almost the same as code shown here so I'm totally confused. What I'm doing wrong?
Edit:
Just in case, here is how I fetch authorization token (it looks like that it works fine), maybe my parsing is wrong:
def getNewAndroidAuthorizationToken() :
request = urllib2.Request("https://www.google.com/accounts/ClientLogin")
data = urllib.urlencode({'accountType' : 'HOSTED_OR_GOOGLE',
'Email' : 'someaccount#gmail.com',
'Passwd' : 'asdjsdfa',
'service' : 'ac2dm',
'source' : 'com.mycompany.mypackage',})
request.add_data(data)
content = urllib2.build_opener().open(request)
lines = content.readlines()
for line in lines :
if line.find("Auth=")==0 :
return line[5:]
return
C2DM is deprecated. Developers are encouraged to switch to GCM, C2DM will be supported for a short time. Simple API instead of ClientLogin and oAuth2 which are not supported.
http://developer.android.com/guide/google/gcm/index.html