Firebase Admin Send Multicast not getting called or working - python

I'm working on django project in which i need to send notifications to the users using firebase admin sdk. but when ever i tried to send notification i see no logs for messaging.send_multicast(message). can anyone help me on this?
message = messaging.MulticastMessage(
data={
'data': str(self.data)
},
tokens=registration_tokens,
)
print('message', message)
response = messaging.send_multicast(message)
print('response', response.success_count, response.failure_count)

The code above to send a multicast data message is correct and should work. Do you get any errors?
Also have you made sure to initialise the Firebase admin SDK with correct credentials:
import firebase_admin
from firebase_admin import credentials, messaging
cred = credentials.Certificate(<credentials_path>)
default_app = firebase_admin.initialize_app(cred)
If you want to send a notification that's visible on the user's phone, should use the notification attribute, like so:
message = messaging.MulticastMessage(
notification=messaging.Notification(
title="Notification Title",
body="Notification Text",
),
tokens=registration_tokens
)
response = messaging.send_multicast(message)
print('response', response.success_count, response.failure_count)

Related

how to get HTTP V1 Access Token for firebase?

I want to add HTTP V1 Access Token to my firebase cloud messaging service. I'm using python fore retrieving the access token.
import firebase_admin
from firebase_admin import credentials
cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)
I'm using this code. It's working fine but the expiry date for the access token is only one day. What is the way to increase the expiry date?
I want to get this bearer token. In the authorisation section.
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message":{
"token":"token_1",
"data":{},
"notification":{
"title":"FCM Message",
"body":"This is an FCM notification message!",
}
}
}
To get the "access token" that is needed in the "Authorization" header, you will need to authenticate using the OAuth 2.0 process. This document explains how to get it with python.
Since you are already using the admin SDK, it will do the authentication for you. And, instead of making the HTTP request yourself, you can call the SDK methods for sending messages. See this example:
import firebase_admin
from firebase_admin import credentials
cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)
message = messaging.Message{
"token" = "token_1",
data={
'score': '850',
'time': '2:45',
}
}
response = messaging.send(message)
print('Successfully sent message:', response)
Here you can see an example with more options and details.

AWS Cognito OAuth configuration for Flask Appbuilder

I am setting up RBAC with Airflow, and testing locally to start. I have provisioned an AWS Cognito User Group via the console. Additionally, I have a webserver_config.py file I have mounted to my Airflow docker container to set up OAuth with RBAC.
Relevant section in my webserver_config.py file:
COGNITO_URL = os.getenv('COGNITO_URL')
CONSUMER_KEY = os.getenv('COGNITO_CLIENT_KEY')
SECRET_KEY = os.getenv('COGNITO_CLIENT_SECRET')
# When using OAuth Auth, uncomment to setup provider(s) info
# Google OAuth example:
OAUTH_PROVIDERS = [{
'name':'AWS Cognito',
'whitelist': ['#company.com'], # optional
'token_key':'access_token',
'icon':'fa-amazon',
'remote_app': {
'base_url': os.path.join(COGNITO_URL, 'oauth2/idpresponse'),
# 'base_url': COGNITO_URL,
'request_token_params':{
'scope': 'email profile'
},
'access_token_url': os.path.join(COGNITO_URL, 'oauth2/token'),
'authorize_url': os.path.join(COGNITO_URL, 'oauth2/authorize'),
'request_token_url': None,
'consumer_key': CONSUMER_KEY,
'consumer_secret': SECRET_KEY,
}
}]
Variables are as follows:
COGNITO_URL: The domain name I have created in the "App Integration" section of my user pool
COGNITO_CLIENT_KEY: The app client id for my app in the "App Clients" section of my user pool
COGNITO_CLIENT_SECRET: The app client secret for my app in the "App Clients" section of my user pool
In the Cognito UI, I have the following settings for my App Client:
enter image description here
Basically, I have set the endpoints as they should be on my local machine when testing. I have fiddled with both the http://localhost:8083/oauth2/idpresponse and http://localhost:8083/admin (normal home page for Airflow) routes and received the same error.
I think that the issue is that the URI the client is trying to request and the URI specified do not match. I tried following the advice at https://stackoverflow.com/a/53602884/13717098, but when I extracted that URI and saved it in the Cognito console, I continue to get the same error. I am looking for help identifying the URI needed. The request I've identified per the linked post is: /oauth2/authorize?response_type=code&client_id=269vguq386076suj80vpq4ctmj&redirect_uri=http%3A%2F%2Flocalhost%3A8083%2Foauth-authorized%2FAWS%2520Cognito&scope=email+profile&state=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZXh0IjpbImh0dHA6Ly9sb2NhbGhvc3Q6ODA4My9ob21lIl19.CcuxpZyuVIqW0GtnNL219Xkg1IftE0tzFiVilR6b4us I would appreciate any help with identifying the URI and/or its associated patterns.
Edited for spacing.
Flask builder library uses the name of the config object as value in redirect_uri.
Set callback value to: http://localhost:8083/oauth-authorized/AWS%20Cognito instead of http://localhost:8080/oauth2/idresponse in AWS Cognito client. This should solve the redirection issue.
The real problem will start for userinfo endpoint as AWS cognito uses OpenID auth pattern.
aws-cognito-client
EDIT
AWS Cognito has oauth2/userinfo endpoint for receiving user information. To retrieve the userinfo, you're supposed to send openid scope along with your request. Following is my webserver_config.py.
from airflow.www_rbac.security import AirflowSecurityManager
from flask_appbuilder.security.manager import AUTH_OAUTH
import os
import json
class CognitoSecurity(AirflowSecurityManager):
def oauth_user_info(self, provider, response=None):
if provider == "aws_cognito":
me = self.appbuilder.sm.oauth_remotes[provider].get("userInfo")
data = json.loads(me.raw_data)
print("User info from aws_cognito: {0}".format(data))
return {"username": data.get("username"), "email": data.get("email")}
else:
return {}
AUTH_TYPE = AUTH_OAUTH
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Admin"
COGNITO_URL = ""
CONSUMER_KEY = ""
SECRET_KEY = ""
OAUTH_PROVIDERS = [{
'name':'aws_cognito',
'whitelist': ['#positsource.com'], # optional
'token_key':'access_token',
'url': COGNITO_URL,
'icon': 'fa-amazon',
'remote_app': {
'base_url': os.path.join(COGNITO_URL, 'oauth2/idpresponse'),
'request_token_params': {
'scope': 'email profile openid'
},
'access_token_url': os.path.join(COGNITO_URL, 'oauth2/token'),
'authorize_url': os.path.join(COGNITO_URL, 'oauth2/authorize'),
'request_token_url': None,
'consumer_key': CONSUMER_KEY,
'consumer_secret': SECRET_KEY,
}
}]
SECURITY_MANAGER_CLASS = CognitoSecurity
This should get the airflow webserver working with AWS cognito. Roles and permissions management can be done by you.

Can't fetch slack user profile information with API

Thank you so much in advance. I am trying to fetch user profile information through slack_authentication. Although the app is successfully authenticated with Slack, it could not get email and username.
{'ok': True, 'access_token': 'xoxp-xXXXXXXXXXXXXXXXX', 'scope': 'identify,channels:read,users.profile:read,chat:write:bot,identity.basic', 'user_id': 'XXXXXXXXX', 'team_id': 'XXXXXXXX', 'enterprise_id': None, 'team_name': 'test', 'warning': 'superfluous_charset', 'response_metadata': {'warnings': ['superfluous_charset']}}
I tried to add identify scope instead of identity.basic because slack doesn't allow you to use both identity.basic and other scopes.
The code is below:
#bp.route('/redirect', methods=['GET'])
def authorize():
authorize_url = f"https://slack.com/oauth/authorize?scope={ oauth_scope }&client_id={ client_id }"
return authorize_url
#bp.route('/callback', methods=["GET", "POST"])
def callback():
auth_code = request.args['code']
client = slack.WebClient(token="")
response = client.oauth_access(
client_id=client_id,
client_secret=client_secret,
code=auth_code
)
print(response)
Additional
I have realized how to get users info. I updated the code to like this.
The code is updated like below:
oauth = client.oauth_access(
client_id=client_id,
client_secret=client_secret,
code=auth_code
)
user_id = oauth['user_id']
response = client.users_info(user=user_id)
But this error occurs:
The server responded with: {'ok': False, 'error': 'not_authed'}
Your code looks like an installation routine for a Slack app using OAuth. But it does not contain a call to get a user profile.
To get the profile of a user you can call users.info and provide the ID of the user you are interested in.
Examples:
response = client.users_info(user=ID_OF_USER)
assert(response)
profile = response['user']['profile']
email = response['user']['profile']['email']
In order to retrieve the user's profile and email address you need these scopes:
- users:read
- users:read.email
The identity scopes are unrelated to the user profile. They are used for the "Sign-in with Slack" approach only, where you can authenticate with a Slack user on a 3rd party web site.
Finally, just to clarify, because this is often misunderstood: You only need to run through the OAuth installation routine once. The routine will yield you a token for the workspace, which you can store and use for any further calls to the API for that workspace.
Update to "Additional"
You are not using the API correctly.
You need to first complete the Oauth flow and collect the access token, which is in the response from client.oauth_access.
Then you need to initialize a new WebClient with the token you received. With the new client you can then access all API methods, like users.info etc.
Again: You should run through the OAuth process one time only and store the received token for later use.
Example:
oauth_info = client.oauth_access(
client_id=client_id,
client_secret=client_secret,
code=auth_code
)
access_token = oauth_info['access_token'] # you want to store this token in a database
client = slack.WebClient(token=access_token)
user_id = oauth_info['user_id']
response = client.users_info(user=user_id)
print(response)

Python Firebase Admin SDK appears successful but I never receive the notification

I'm attempting to use the Python Firebase Admin SDK to send push notifications for my mobile app. I've tested it with the notification composer in the Firebase Console, so I know my device can receive push notifications, but when I try to use the SDK I never receive anything. Nor do I see the notification listed on the Firebase console notification page.
Here's the exact code(minus my personal info) that I'm using to send the notification:
import firebase_admin
from firebase_admin import credentials, messaging
token = "registration token"
creds = credentials.Certificate('path/to/cert.json')
app = firebase_admin.initialize_app(creds)
msg = messaging.Message(data={'title': 'Test'}, token=token)
print(messaging.send(msg, app=app))
This returns a URL that follows the format /project/<project name>/messages/<message ID> but that URL doesn't work for me. It will just redirect me to the Firebase console base domain and a blank screen. Also, the notifications should be listed under /notifications shouldn't they?
I had had this problem for a week. But it was resolved. Follow these:
Make sure your APNs Certificates or APNs Authentication Key were uploaded in Cloud Messaging settings in Firebase Console
Sure that you use the correct FCM token when sending a firebase.messaging.Message which included apns (messaging.APNSConfig).
Check your AppDelegate.m file was setup following Firebase Docs. In my case, I forgot add [FIRMessaging messaging].APNSToken = deviceToken; in function application:didRegisterForRemoteNotificationsWithDeviceToken:. Keep in mind that the response when you send a message in your server did not say anything about the push notification to your iOS devices even you received a message (it did not contain a notification). And I also don't know how to check whether notification delivered or not.
My python server code:
def push_notification():
title = "Your title"
message = "Your message"
ntf_data = {"key": "value"}
fcm_token = "your_fcm_token"
topic = "your_topic"
# apns
alert = ApsAlert(title = title, body = message)
aps = messaging.Aps(alert = alert, sound = "default")
payload = messaging.APNSPayload(aps)
# message
msg = messaging.Message(
notification = messaging.Notification(
title = title,
body = message
),
data = ntf_data,
token = fcm_token,
topic = topic,
apns = messaging.APNSConfig(payload = payload)
)
# send
res = messaging.send(msg)
And frontend react-native notification listener code:
onNotificationListener = firebase.notifications().onNotification((notification) => {
console.log("received notification:", notification)
}
Feel free to ask if there is any problem in my answer or if you need more information. Happy coding.
The return value is a message ID string, and currently it doesn't point to anything (i.e. not a valid URL). It's just the unique ID that FCM has assigned to your notification, and it indicates the notification has been successfully handed off to FCM for delivery. Also, I believe that notifications sent from the SDK do not appear in the Firebase console. You need an actual client (Android, IOS or web) to test this flow end-to-end.

Can't register webhook for Twitter Account Activity API [python3]

I'm trying to set up a Twitter app using the Account Activity API, to replace my old set up which used the user streaming endpoint. I want to be able to get DM messages to one user sent to a particular URL in real time.
Following these migration instructions, I've set up a webhook endpoint on my site, as described here. I've checked that process is working, by making sure that when I open https://example.com/webhook_endpoint?crc_token=foo in my browser, I get a token in response.
Now I'm trying and failing to register my webhook. I'm using the following code, and getting a 403 response.
from requests_oauthlib import OAuth1Session
import urllib
CONSUMER_KEY = 'my consumer key'
CONSUMER_SECRET = 'my consumer secret'
ACCESS_TOKEN = 'my access token'
ACCESS_SECRET = 'my access secret'
twitter = OAuth1Session(CONSUMER_KEY,
client_secret=CONSUMER_SECRET,
resource_owner_key=ACCESS_TOKEN,
resource_owner_secret=ACCESS_SECRET)
webhook_endpoint = urllib.parse.quote_plus('https://example.com/webhook/')
url = 'https://api.twitter.com/1.1/account_activity/all/env-beta/'
'webhooks.json?url={}'.format(webhook_endpoint)
r = twitter.post(url)
403 response content: {"errors":[{"code":200,"message":"Forbidden."}]}
I can successfully post a status using the same session object and
r = twitter.post('https://api.twitter.com/1.1/statuses/update.json?status=Test')
What am I doing wrong here?
This turned out to be due to a combination of:
Not having created an environment here: https://developer.twitter.com/en/account/environments as described here: https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/getting-started-with-webhooks
using the wrong consumer secret in the function that created the token returned at the /webhook endpoint

Categories