Send FCM notification to multiple tokens using Plokko Firebase - php

I am using the Plokko FCM v1 library: https://github.com/plokko/php-fcm-v1
so far i am using a loop to send to multiple tokens, and it is becoming too slow as each loop is waiting for the notification to be sent, how to send to multiple tokens at once like we used to do it in legacy HTTP code.
i tried making it an array, a comma seperated value both times i am getting
The registration token is not a valid FCM registration token
any help would be appriciated
thank you

You must use registration_ids instead of to in creating an object and make an array of devices token and assign it to registration_ids as follow
const id = deviceIds;
const Title = "Title";
const message = "This is testing notification";
const messaged = {
registration_ids: id, //// multiple devices
// to: id, //// use for single device
collapse_key: 'appName',
notification: {
title:Title,
body: message
}
};
await fcm.send(messaged, function(err, response){
if (err) {
console.log(err)
// result(null,{success:false,message:"Some Error", data:err});
} else {
console.log(response)
}
});

Related

How to take a string from JSON in Angular

So I basically trying to set a token on my localStorage. I make a request to my API in PHP and this is the code:
login() {
const body = JSON.stringify({
"usuario":"juanma",
"password":"1234"});
console.log(body);
const params = new HttpParams();
const headers = new HttpHeaders();
this.http.post<AuthResponse>("http://localhost:8000/login", body, {'headers':headers,'params':params})
.subscribe(data => localStorage.setItem('token', data.token.toString()));
}
I actually get the token, I even can see it on the console.log (not appears on the code right now, but I tried it and it does appear).
AuthResponse is a model I created that replicates the JSON return from the post method.
However Im not being able to set the token like a string on localStorage, and I get this:
I'm really lost with this. If anyone can help, I'll be thankfull!
EDIT: Added screenshot of the console.log(data.token) inside the subscribe:
EDIT 2: Now I get the token right! Problem is that I need to do the method 2 times in order to make it work.
As you can see, the first time I made the method, it gives the 'undefined' value.
You just need to replace your data.token.toString() to data.token.token
login() {
const body = JSON.stringify({
"usuario":"juanma",
"password":"1234"});
console.log(body);
const params = new HttpParams();
const headers = new HttpHeaders();
this.http.post<AuthResponse>("http://localhost:8000/login", body, {'headers':headers,'params':params})
.subscribe(data => localStorage.setItem('token', data.token.token));
}

PHP webpush library (Minishlink\WebPush) no event.data

I have configured webpush and all is going well... I have registered the service-worker.js, can request permission, save the subscription to my db and send a push notification from the server using the library which is installed.
When I send the push notification
[
'subscription' => Subscription::create($subs_arr),
'payload' => '{"title":"test title","msg":"Hello World!", "icon":"https://www.newhomesforsale.co.uk/media/chevron.png","url":"https://www.newhomesforsale.co.uk/"}'
]
];
I get a success message:
[v] Message sent successfully for subscription https://fcm.googleapis.com/fcm/send/e2JHJ2YcIfM:APA91bHwU7CruFTDkpAH-zbnJRNhvJEK-mCze2hFNa48mdK8pk-oWuXJUn57Ai9Nw0d-skviCfJ40g1yX7qWKucGHPF3jeNyhkJfZ-8kpxYJNQowrAR561b0dQZJAseL_eBsJRMrxnDP.
and a push message appears in the browser - great.
The problem I have is that the service-worker file doesn't seem to see the payload information because the message displays even as simply
Oh No - no data {"isTrusted": true}
Service-worker file:
self.addEventListener('push', function(event) {
if (!(self.Notification && self.Notification.permission === 'granted')) {
return;
}
const sendNotification = body => {
// you could refresh a notification badge here with postMessage API
const title = "Web Push example";
return self.registration.showNotification(title, {
body,
});
};
if (event.data) {
const message = event.data.text();
event.waitUntil(sendNotification(message));
} else {
do_serverlog('Push event but no data');
sendNotification("Oh No - no data" + JSON.stringify(event));
}
});
Would be great to get the last piece of the puzzle to figure out how to correctly send/read the payload.
I have found that I made a mistake passing throught the keys into the subscription ($subs_arr).
It seems that if you have provide the endpoint, but not the keys, the push notification still works, but with the data stripped out. This sidetracked me as I had assumed that it wouldn't work at all if the keys were missing.
I thought maybe this might help someone at some point.

Redis publish and subscription not working on dynamic keys

my requirement is to publish message for specific user.
Controller
$messageQueueKey=(string)$receiver; (receiver_id)
$redis->publish($messageQueueKey, json_encode($data));
Server.js //Node js
var handshakeData = socket.request;
var messageQueueKey=handshakeData._query['userid'];
clients[socket.id] = socket;
var redisClient = redis.createClient();
redisClient.subscribe(messageQueueKey);
// redisClient.subscribe('message');
redisClient.on('message', function(channel, message)
{
var data = JSON.parse(message);
if(typeof connectedClients[data['receiver']] === 'undefined'){}
else
{
connectedClients[data['receiver']].socket.emit(channel, message);
}
});
However my code works for hard coded key 'message' but receivers receives multiple messages that is why i want to publish and subscribe each user on different keys based on their auth id
That's fine! if the user is receiving multiple message you can ignore the one :P

facebook_session has no method graphCall

I'm using the DracoBlue node-facebook-client and passport.js to authenticate a user into my app, then check if they are a member of a specific group.
I retrieve the users profile and access token then using the facebook_client try to get a session with the access token.
I'm not sure if the session being created properly because when I try using the method graphCall it throws the following error:
"500 TypeError: Object function (cb) { var session = new FacebookSession(self, access_token); cb(session); } has no method 'graphCall'"
A further source of information is found here.
Although not a php question. This is a node.js port of the php facebook client api so someone who uses that may have had the same problem.
Any help is greatly appreciated.
Thanks.
/* get the facebook client using ID and secret */
var facebook_client = new FacebookClient(
clientID, // configure like your fb app page states
clientSecret, // configure like your fb app page states
{
"timeout": 10000 // modify the global timeout for facebook calls (Default: 10000)
}
);
/*
* Define the facebook stragety
*/
passport.use(new FacebookStrategy({
clientID: clientID,
clientSecret: clientSecret,
callbackURL: "http://localhost:3000/auth/facebook/callback",
scope: 'user_groups' //Ask user to access their groups. Used for finding whether user is member of group
},
function(accessToken, refreshToken, profile, done) {
console.log('accessToken: ' + accessToken);
console.log('facebook_client: ' + facebook_client);
var facebook_session = facebook_client.getSessionByAccessToken(accessToken);
console.log('facebook_session: ' + facebook_session);
facebook_session.graphCall('/me?fields=groups')(function(result){
if(!result.error)
{
console.log(groups.data);
}
else
{
console.log('Error: ' + result.error.message);
console.log('nane: ' + result.data);
}
});
console.log('profile.groups ' + profile.user_groups);
console.log('accessToken ' + accessToken);
console.log('refreshToken ' + refreshToken);
done(null, profile);
}
));
The syntax was incorrect.
To retrieve the session I had to write the following:
facebook_client.getSessionByAccessToken(accessToken)(function(session){
});
I'm relatively new to node.js and keep forgetting I need to use callbacks.

Facebook Graph API, how to get users email?

I'm using the Graph API, but I can't figure out how to get a logged-in users email address.
The intro to Graph states "The Graph API can provide access to all of the basic account registration data you would typically request in a sign-up form for your site, including name, email address, profile picture, and birthday"
All well and good, but how do I access that info?
This is what I have so far:
$json = $facebook->api('/me');
$first = $json['first_name']; // gets first name
$last = $json['last_name'];
The only way to get the users e-mail address is to request extended permissions on the email field. The user must allow you to see this and you cannot get the e-mail addresses of the user's friends.
http://developers.facebook.com/docs/authentication/permissions
You can do this if you are using Facebook connect by passing scope=email in the get string of your call to the Auth Dialog.
I'd recommend using an SDK instead of file_get_contents as it makes it far easier to perform the Oauth authentication.
// Facebook SDK v5 for PHP
// https://developers.facebook.com/docs/php/gettingstarted/5.0.0
$fb = new Facebook\Facebook([
'app_id' => '{app-id}',
'app_secret' => '{app-secret}',
'default_graph_version' => 'v2.4',
]);
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
$response = $fb->get('/me?locale=en_US&fields=name,email');
$userNode = $response->getGraphUser();
var_dump(
$userNode->getField('email'), $userNode['email']
);
Open base_facebook.php
Add Access_token at function getLoginUrl()
array_merge(array(
'access_token' => $this->getAccessToken(),
'client_id' => $this->getAppId(),
'redirect_uri' => $currentUrl, // possibly overwritten
'state' => $this->state),
$params);
and Use scope for Email Permission
if ($user) {
echo $logoutUrl = $facebook->getLogoutUrl();
} else {
echo $loginUrl = $facebook->getLoginUrl(array('scope' => 'email,read_stream'));
}
Just add these code block on status return, and start passing a query string object {}. For JavaScript devs
After initializing your sdk.
step 1: // get login status
$(document).ready(function($) {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
console.log(response);
});
});
This will check on document load and get your login status check if users has been logged in.
Then the function checkLoginState is called, and response is pass to statusChangeCallback
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
Step 2: Let you get the response data from the status
function statusChangeCallback(response) {
// body...
if(response.status === 'connected'){
// setElements(true);
let userId = response.authResponse.userID;
// console.log(userId);
console.log('login');
getUserInfo(userId);
}else{
// setElements(false);
console.log('not logged in !');
}
}
This also has the userid which is being set to variable, then a getUserInfo func is called to fetch user information using the Graph-api.
function getUserInfo(userId) {
// body...
FB.api(
'/'+userId+'/?fields=id,name,email',
'GET',
{},
function(response) {
// Insert your code here
// console.log(response);
let email = response.email;
loginViaEmail(email);
}
);
}
After passing the userid as an argument, the function then fetch all information relating to that userid. Note: in my case i was looking for the email, as to allowed me run a function that can logged user via email only.
// login via email
function loginViaEmail(email) {
// body...
let token = '{{ csrf_token() }}';
let data = {
_token:token,
email:email
}
$.ajax({
url: '/login/via/email',
type: 'POST',
dataType: 'json',
data: data,
success: function(data){
console.log(data);
if(data.status == 'success'){
window.location.href = '/dashboard';
}
if(data.status == 'info'){
window.location.href = '/create-account';
}
},
error: function(data){
console.log('Error logging in via email !');
// alert('Fail to send login request !');
}
});
}
To get the user email, you have to log in the user with his Facebook account using the email permission. Use for that the Facebook PHP SDK (see on github) as following.
First check if the user is already logged in :
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
If he his not, you can display the login link asking for the email permission :
if (!$user) {
$args = array('scope' => 'email');
echo 'Login with Facebook';
} else {
echo 'Logout';
}
When he is logged in the email can be found in the $user_profile array.
Hope that helps !
Assuming you've requested email permissions when the user logged in from your app and you have a valid token,
With the fetch api you can just
const token = "some_valid_token";
const response = await fetch(
`https://graph.facebook.com/me?fields=email&access_token=${token}`
);
const result = await response.json();
result will be:
{
"id": "some_id",
"email": "name#example.org"
}
id will be returned anyway.
You can add to the fields query param more stuff, but you need permissions for them if they are not on the public profile (name is public).
?fields=name,email,user_birthday&token=
https://developers.facebook.com/docs/facebook-login/permissions
You can retrieve the email address from the logged in user's profile. Here is the code snippet
<?php
$facebook = new Facebook(array(
'appId' => $initMe["appId"],
'secret' => $initMe["appSecret"],
));
$facebook->setAccessToken($initMe["accessToken"]);
$user = $facebook->getUser();
if ($user) {
$user_profile = $facebook->api('/me');
print_r($user_profile["email"]);
}
?>
First, activate your application at the Facebook Developer center. Applications in development mode are not allowed to retrieve the e-mail field.
If the user is not logged in, you need to login and specify that your application/site will need the e-mail field.
FB.login(
function(response) {
console.log('Welcome!');
},
{scope: 'email'}
);
Then, after the login, or if the user is already logged, retrieve the e-mail using the Facebook API, specifying the field email:
FB.api('/me', {fields: 'name,email'}, (response) => {
console.log(response.name + ', ' + response.email);
console.log('full response: ', response);
});
https://graph.facebook.com/me
will give you info about the currently logged-in user, but you'll need to supply an oauth token. See:
http://developers.facebook.com/docs/reference/api/user
The email in the profile can be obtained using extended permission but I Guess it's not possible to get the email used to login fb. In my app i wanted to display mulitple fb accounts of a user in a list, i wanted to show the login emails of fb accounts as a unique identifier of the respective accounts but i couldn't get it off from fb, all i got was the primary email in the user profile but in my case my login email and my primary email are different.
Make sure your Facebook application is published. In order to receive data for email, public_profile and user_friends your app must be made available to public.
You can disable it later for development purposes and still get email field.
The following tools can be useful during development:
Access Token Debugger: Paste in an access token for details
https://developers.facebook.com/tools/debug/accesstoken/
Graph API Explorer: Test requests to the graph api after pasting in your access token
https://developers.facebook.com/tools/explorer
Make sure to fully specify the version number of the API as something like "v2.11" and not "2.11"
I'm not sure what it defaults to if this is incorrect, but I got some odd errors trying to just retrieve the email when I missed the v.
For me the problem with collecting user's email addres on PHP side (getGraphUser() method) was, that the default behavior of facebook-rendered button (on WEBSIDE side, created with xfbml=1) is to implicity calling FB.login() with the scope NOT including "email".
That means you MUST:
1) call
FB.login(....,{scope: email})
manifestly, creating your own button to start login process
OR
2) add scope="email" attribute to the xfbml button
<div class="fb-login-button" data-size="large" data-button-type="continue_with" data-
layout="rounded" data-auto-logout-link="false" data-use-continue-as="true" data-
width="1000px" scope="email"></div>
to be able to collect email address on PHP side.
Hope it helps.

Categories