Sending notification to GCM from Django via FCM token - django

I am doing my first steps in Django-Android interaction, and I am bit confused about the logic how FCM technology works. I have installed django-fcm via pip, and now my goal is to send a notification to Android device via FCM token that has been sent to server by Android device via REST resource.
The third-party Android developers tell that they would give me only the FCM token and I should be able to send a notification. And I'm a bit confused by the following code snippet from the doc
devices = FCMDevice.objects.all()
What is FCM device ? And how does JSON code in the example:
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"
}
}
...related to this:
device = FCMDevice.objects.all().first()
device.send_message("Title", "Message")
device.send_message(data={"test": "test"})
device.send_message(title="Title", body="Message", icon=..., data={"test": "test"})
THE QUESTION IS what is the minimum code snippet to send the simplest notification to an Android device identified by its FCM token

To send a notification via your django app server, you need to:
Install django-fcm and add 'fcm_django' to your INSTALLED_APPS.
Run migrations so as to have a device relation ready
in your database.
Assuming you already can send notifications from the Firebase
console, go to your Firebase console settings. On the Cloud
Messaging tab, copy the Server Key. Save this key in your django
configuration settings as FCM_APIKEY = <your_api_key>
Go to your android device and retrieve the Token, the docs for this
are at
https://firebase.google.com/docs/cloud-messaging/android/client
Now create a Device instance in django, use the retrieved token as
the reg_id.
To send a notification, you can send a notification using
device_instance.send_message
(notification = { "body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"})
To fully understand how django-fcm works, I would advice that you actually go through the source code. If an open source package is disturbing me, actually viewing the source code and reading the comments is sometimes enlightening. django-fcm is a small and simple package. The utils.py file is the most important. That is where the message is composed and sent to Firebase using the python's requests package. To understand this file. Please also read the docs for firebase at: https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json

First of all, FCMDevice is a django model object which contains the data about a registered device, to which notifications can be sent.
It is expected, that you provide that data. When you mobile device/browser gets that data from its FCM token from fcm library, it is expected that you register that token within your backend that uses the fcm-django library.
Meaning, you create an object within your database with using the model FCMDevice from the library.
Minimal code required to send the notification is exactly that, which you have posted in this post.
I believe you should perhaps read some django tutorials, to better understand what models actually are.

Related

No data posts by my Kotlin appliaction to Django Rest Framework

I made a Authorizing system with SMS which gets number of an application then makes account and with verify code it let user to login. the problem is that when I send data by Retrofit in Kotlin as POST ,it sends no data (None) to server and Django logs show that no data sent for it. I know my Django API is working truly because of that POSTMAN works with it but my Kotlin application doesn't. Here I used APIService "Kotlin Intrface" class like this you see as below:
#FormUrlEncoded
#POST("v1/register/")
suspend fun RegisterRequest(
#Field("mobile") mobile: String
):Response<Reply>
I expected to see in logs that data sends for server but it doesnt work.
Also maybe you say that it needs Header but no ,cuz of I tried to set header for it also its Register and doesn't need token or anything like this and there's no persmission for it in server side.

DRF, Firebase FCM. Sending push notifications

I am creating a DRF project and want to implement sending push notifications to devices.
I have configured firebase in Django settings. But after that I faced a problem as I can't send test notification even from admin, I get an error:
enter image description here
I understand that FCM registration token is required, but there is no way I can get it on backend side. Please advise if anyone has come across how is it possible to generate registration token on backend.
You should get the token on front.end side with JS, and also have functions for receiving messages in background/foreground on front.end.
The token can then be saved in your database or on firebase, whichever you prefer.

Confusion migrating Parse push to AWS SNS

I am a little confused about this migration path, as described in a recent aws blog post, and its aftermath:
It seems like quite a bit of trouble to have to rely on all my users to update in a timely fashion so that GCMSenderIDs can be attached to my existing parse data along with modified/valid device tokens.
Also, what happens to new installations after the migration is complete? In the guide it says no changes need to be made to client side code, but doesn't this require that the SNS sdk is installed so that new installations can be added to the client list?
Considering all this, wouldn't it make a lot more sense to simply forget about the old parse data and just push a client/app update that works solely with SNS and reregister all the devices that way? Why go through all the trouble to integrate with Parse when we are getting rid of it anyways?
AllTheTime,
Your existing Android user push tokens on Parse.com will no longer be valid after January 28, 2017 as Parse owns the API Server Key associated with the Sender ID that was granted the token. If you wish to reach those existing users via Push Notifications after January, you must update the existing Parse.com client app with your own Sender ID and have the app generate a new registration Id (token) associated with your Sender ID. There is no other way for you to convert the existing tokens over to SNS or any another 3rd party.
The SNS SDK is not required for the migration but it would make sense to integrate the SNS SDK when you update the app to retrieve new tokens using your Sender ID. At the time of token registration, the app can update the Parse.com database with the newly issued token AND also create a new Platform Endpoint with SNS.
As for post Parse Push migration and handling the new app installations, my suggestion is to build an after-save “webhook” on the _Installation class on Parse.com. The “webhook” would trigger any http endpoint when a row is created or updated in the _Installation class. The hook could trigger an API Gateway http endpoint that takes the newly generated or updated token and creates a new SNS platform endpoint. At this point, if you haven’t fully migrated from Parse.com, you can either publish to those tokens via Parse.com or SNS. By the time Jan 28, 2017 rolls around, nearly all your existing users would have launched the updated app and generated a new token or they no longer use your app.
Starting over with just SNS is another option but if you need to reach any of the users who have not updated the app then you would need to continue sending push notifications through Parse.com for those legacy users who have not updated the app AND you would then continue to send push notifications via SNS to those new app installs.
I hope this clarifies the migration for you.
Check out my other SO post regarding the Parse.com GCM Sender ID:
How to migrate off Parse to different SENDER_ID
-Dennis

One-Time User Authentication with SMS Using Django and Twilio

I am writing a back-end in Django for a mobile app I am creating. I need to authenticate a user the first time they open the mobile app through SMS to verify it is a real person. What needs to happen is the following: user enters phone number in app, server then sends SMS message to user with authentication code, user then enters authentication code in app and server verifies that the code they entered in the app is the same one they received through SMS.
I need to use Twilio with my Django project. I just need to know what would be the best way to go about this? The front-end side of this (the mobile app) is not what I am asking about, I am asking about the code on the back-end that should be implemented. I am struggling to find up to date documentation for django-twilio integration that could do this.
Twilio evangelist and maintainer of django-twilio here.
What you're looking to build is something very easy to do, I can outline the steps for you here:
Create a Django model that stores a user's number and a generated passcode
When a new user is created, take their number and SMS them the code using the Twilio REST API
When they enter the passcode you sent them, cross reference it with the one stored in the database.
If the number is right: verify them, if not, tell them it is wrong and offer to send them an SMS again.
You can use django-passcode as an app in your project.
It exposes APIs to "register" a mobile number and "verify" through SMS based passcode. It uses mobile number and device id pair as unique. It also generates and returns a token for future authorization requests from mobile app. You can use Twilio or any other SMS api to send sms.
https://github.com/sgurminder/django-passcode
I appreciate your feedback for django-passcode
Disclaimer: I'm the maintainer of Django-phone-verify
What you're looking to accomplish is very easy with django-phone-verify app. It comes with Twilio already integrated and few endpoints which you can extend as per your use case.
This package aims at verifying if a phone number requested by a particular client belongs to them. It also takes care of ensuring that the same device provides the verification of passcode which intially requested a passcode to be sent, saving you a few hours of work.
This package also doesn't messes up with your current user model at all. You're free to use this package exactly for one thing: verifying phone numbers. Whether you do it for users, companies, etc. depends on your use-case.
It follows Unix philosphy of Do one thing; do it well
Installation
pip install django-phone-verify
Configuration
Add app to INSTALLED_APPS:
# In settings.py:
INSTALLED_APPS = [
...
'phone_verify',
]
Add settings in your settings.py file:
# Settings for phone_verify
PHONE_VERIFICATION = {
'BACKEND': 'phone_verify.backends.twilio.TwilioBackend',
'TWILIO_SANDBOX_TOKEN':'123456',
'OPTIONS': {
'SID': 'fake',
'SECRET': 'fake',
'FROM': '+14755292729'
},
'TOKEN_LENGTH': 6,
'MESSAGE': 'Welcome to {app}! Please use security code {otp} to proceed.',
'APP_NAME': 'Phone Verify',
'OTP_EXPIRATION_TIME': 3600 # In seconds only
}
Migrate the database:
python manage.py migrate
You get two endpoints (Check API docs), one for registration of phone number and other to verify the passcode. You may override verify endpoint to also create a user as described in the usage docs: https://github.com/CuriousLearner/django-phone-verify/blob/master/docs/usage.rst
Recently I was looking for any library or scheme to sign-in/sign-up users through sms (send sms code and then validate).
Short solution:
Create sms model to generate code for phone number
Send sms with code to client (for example, use twillio)
User got code. And send phone_number + code
Validate it. Response any useful information
Also:
You must to use async code or celery to send sms
Add sms lifetime (for example, 30 seconds)
Clean phone number to valid format
Get or create user by phone number
You may to use this library, for example:
https://github.com/a1k89/django-rest-sms-auth

Mirror API send timeline item to particular user

I need to send timeline item to particular subscribed user using Mirror API. I have the user's email id. How can I achive this?
Thanks
Update:
I have GDK app, companion app(which runs on Android mobile device) and Mirror API app. Both GDK app and companion paired via Bluetooth. My use case is I have to send timeline item to uesr if he reached particular location. We are using ibeacon to check user's location. When user reached that particular area, companion app detect it(via bluetooth) and send request to mirror app then mirror app will add timeline item to user's glass. Here my question is how to add the timeline item to one particular user?(not to all subscribed users) And what parameter should I pass to mirror app from companion app?(I was thinking to send the user's email id)
The user will have needed to log into your service using OAuth2 and have granted specific permission for you to access their timeline using the role https://www.googleapis.com/auth/glass.timeline. You should request "offline" access so you will receive both an auth token and a refresh token, which you can use to get a new auth token after an hour.
You will need this auth token when you send a card to the timeline, which also serves as an identifier in this case. Having their email id is not enough, and you don't need it.
See https://developers.google.com/glass/develop/mirror/authorization for some code samples and details.
Update:
So it sounds like you have the following overall work flow:
User creates an account on your website (which is where the Mirror API app is hosted). As part of this, they authorize access to their Glass and either give you their email address or authorize you to get it via Google's API.
You'll store this information (auth_token and refresh_token) in a data store somewhere, indexed against their email address.
They will also install your app on their phone, and it has access to the email address as well.
When the mobile app detects an ibeacon marker it is interested in, it connects to your web service and sends the email address and location.
Your web service looks up the email address, gets the access token to authenticate the connection to the Mirror service, and sends a message to Glass with the location information.
This is a generally reasonable workflow, but there are a couple of important points to make:
The Mirror API is well tuned to sending things to just one person at a time. You sound worried about sending bulk results, but as long as you use the auth token for just one user, it will send it to just that user.
You're using the email address as an index to the entire user account. While this is simple to implement, this is not the best solution, since it means that anyone who has a person's email address and the URL for the endpoint of your service can fake locations. You may consider this an acceptable risk given how you're using the location information (sending it back to the user), but you need to think about how the service could be misused.
You can mitigate the risk in a couple of potential ways:
Instead of an easily guessable email address, you can create and use some other userid which the user will need to enter when they first setup the companion app.
The first time (and only the first time) the app wants to connect to the service, it creates and sends a random secret string which it will use as a password and the web service could store this random string. Afterwards, the companion app would need to send this string along with the email address.
Depending on your needs, you could cut out the webapp completely and have the companion app use the Mirror API directly. This would leave the auth tokens on the phone and would greatly reduce the potential chance to have someone spoof your user. It does have a significant downside - although you can use it to send cards to Glass, it becomes more difficult to get responses from Glass back to the companion device.
As I understand your question and comments above, your user has already authenticated with your Mirror API based application, so you already have the required credentials (auth/refresh tokens). Your companion Android application detects a condition (user in a particular area) and sends a request to your remote endpoint in your Mirror API based application.
The companion app, when sending the request to the remote endpoint, needs to send a common piece of information that can be used to identify that user in your Mirror API app. In this case, you're saying you're sending the users email id.
To send a timeline card to only that particular user, I would take the email id that the companion application has sent, query your database to return the credentials that you saved when the user authenticated originally with your Mirror API based app and then use that to create an authenticated Mirror API request that inserts the timeline item for only that user. I don't know what your Mirror API app is written in, but a basic example in Python might take the following form:
# You sent along the email address
userid = notification['MyCompEmailId']
# set timeline card body
timelinecard_body = {
'notification': {'level': 'DEFAULT'},
'text': "You found a beacon!",
'menuItems': [{'action': 'DELETE'}]
}
# Look up the user in our database and
# get their credentials
#
# _credentials_for_user() basically does a "WHERE userid = 'something'" query
user_credentials = _credentials_for_user(userid).get()
# Create a Mirror API service with some credentials.
authed_mirror_service = build('mirror', 'v1', http=user_credentials.authorize(httplib2.Http()))
# Send a timeline card
authed_mirror_service.timeline().insert(body=timelinecard_body).execute()