Can I access subscribeToTopic using #nuxtjs/firebase module? - javascript

I am using #nuxtjs/firebase in a nuxt project. The messaging works, I can send messages from postman via fcm to my website. I can't see any documentation on how I can access the subscribeToTopic.
In my nuxt.config.js I have:
[
'#nuxtjs/firebase',
{
config: {
apiKey: "myapiKey",
authDomain: "myDomain",
projectId: "myProjectId",
storageBucket: "myStorageBucker",
messagingSenderId: "mySenderId",
appId: "myAppId",
measurementId: "myMeasurementId"
},
services: {
auth: {
persistence: 'local',
initialize: {
onAuthStateChangedAction: 'onAuthStateChangedAction',
subscribeManually: false
},
ssr: false
},
messaging: {
createServiceWorker: true,
fcmPublicVapidKey: 'myVapidKey',
inject: fs.readFileSync('./serviceWorker.js')
},
firestore: true
}
}
]
serviceWorker.js has:
self.addEventListener('push', function (e) {
const data = e.data.json();
const options = {
body: data.notification.body,
icon: data.notification.icon,
vibrate: [100, 50, 100],
data: {
dateOfArrival: Date.now(),
primaryKey: '2'
},
};
})
In async mounted I have:
const currentToken = await this.$fire.messaging.getToken()
console.log("token", currentToken)
this.$fire.messaging.onMessage((payload) => {
console.info('Message received. ', payload)
this.$toast.success(payload.data.text + "</br>" + payload.data.additionalInfo, { icon: payload.data.icon });
})
this.$fire.messaging.onTokenRefresh(async () => {
const refreshToken = await this.$fire.messaging.getToken()
console.log('Token Refreshed', refreshToken)
})
This all works as expected.
Apparently I should be able to subscribe to topics, in firebase something like the following can be used:
FirebaseMessaging.getInstance().subscribeToTopic("all")
.addOnCompleteListener { task ->
if (task.isSuccessful) {
//Successfully Subscribed to Notification Service
}else{
//Subscription Notification Service failed
}
}
But, I cannot see how to do that using #nuxtjs/firebase module.

There is no client-side API in the JavaScript SDK to subscribe to a topic. You'll instead need to use a (server-side) Admin SDK to accomplish this.
For example, the subscribeToTopic method you refer to exists in the Node.js SDK and in the Java SDK, but not in the JavaScript/Web or Android SDKs.
I recommend studying the documentation on subscribing a web client to a topic a bit further.
Once you subscribe a client to a topic from the server, the existing client-side code you already have should start receiving messages to that topic too.

Related

Trying to subscribe to topic on Firebase Cloud Messaging gives Error

When i try to subscribe to a topic i get the following error:
.subscribeToTopic is not a function
const messaging = firebase.messaging();
messaging
.requestPermission()
.then(() => {
return messaging.getToken();
})
.then(token => {
messaging
.subscribeToTopic(token, 'allUsers')
.then(response=> {
console.log(JSON.stringify(response));
})
.catch(function(error) {
console.log('Error subscribing to topic:', error);
});
})
.catch(err => {
console.log('Unable to get permission to notify.', err);
});
If I remove that line of .subscribeToTopic and add a POST call via http it works using the following url:
https://iid.googleapis.com/iid/v1/TOKEN/rel/topics/TOPIC_NAME
I took a look to this question and the docs
Cloud Messaging in Cloud Functions: admin.messagin(...).send is not a function
https://firebase.google.com/docs/cloud-messaging/js/topic-messaging
ah i solved it by handling on backend side ( nodeJS ) where the documentation is easy to handle topic.
so in this case we have alr generate token on frontend side then in backend (nodeJS) we tried to subscribe to topic by the token.
so in frontend end when we stream or firebase.messaging().onMessage(payload => { would like to trigger and show the message by topic.
FYI : https://github.com/firebase/firebase-js-sdk/issues/5289#issuecomment-899542765
so from the link we know that
Notification.vue
// these from frontend side ( for example vueJS )
import firebase from 'firebase/app'
import 'firebase/messaging'
// firebase only for get token, onMessaging, request permission check, there is no function to subscribe topic by the token, so we handle on backend side my alternative
then in server.js
// these from backend side ( for examle nodeJS )
const { admin } = require('./firebase-config');
// admin.messaging().sendToTopic()
// admin.messaging().subscribeToTopic()
// admin.messaging().sendToDevice()
if you are looking for the firebase-config.js here is
/*
* Initialize firebase
*/
var admin = require("firebase-admin");
var serviceAccount = require("./firebase.json"); // you can get the .json file on firebase service account .
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://project-xxxxxxx.firebaseio.com"
});
module.exports.admin = admin
my implementation :
app.get('/firebase/notification', (req, res)=>{
const registrationToken = req.body.registrationToken;
admin.messaging().subscribeToTopic(registrationToken, 'myTopic')
.then(response => {
console.log('Successfully subscribed to topic:', response)
const options = notification_options;
const message_notification = {
notification: {
title: 'Yogi Arif Widodo',
body: '2 10 pm',
url: 'https://localhost:8080',
other: 'other data',
}
};
admin.messaging().sendToTopic('myTopic', message_notification, options).then( response => {
so when i tested on firebase console send by topic myTopic my Notification.vue trigger these code
firebase.messaging().onMessage(payload => {
.....console.log
}
You need to use the method send not sendToTopic:
// The topic name can be optionally prefixed with "/topics/".
var topic = 'highScores';
var message = {
data: {
score: '850',
time: '2:45'
},
topic: topic
};
// Send a message to devices subscribed to the provided topic.
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
send() was released and replaced sendtotopic/sendtodevice in version FCM v1
https://firebase.googleblog.com/2018/02/firebase-cloud-messaging-v1-now.html
https://firebase.google.com/docs/cloud-messaging/js/topic-messaging

FCM This site has been updated in the background

So I'm using VueJS with the PWA option enabled. When using Firebase Cloud Messaging (for web app), I'm getting a notification saying: This site has been updated in the background but Only when the tab is not focused or open. If the tab is active, I don't receive anything in the console.
I'm using Postman to send notifications for now, and it returns success
{
"multicast_id": 5364665067527599460,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1550148053476716%2fd9afcdf9fd7ecd"
}
]
}
Here is my main.js
const config = {
apiKey: "API_KEY",
authDomain: "AUTH_DOMAIN",
databaseURL: "DATABASE_URL",
projectId: "PROJECT_ID",
storageBucket: "STORAGE_BUCKET",
messagingSenderId: "SENDER_ID"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.usePublicVapidKey("PUBLIC_VAPID_KEY");
navigator.serviceWorker.register('./firebase-messaging-sw.js')
.then((registration) => {
console.log("Now using registration: " + registration);
messaging.useServiceWorker(registration);
}).catch(err => {
console.log("Error in registration");
console.log(err)
});
My firebase-messaging-sw.js (I never saw the console log thats inside setBackgroundMessageHandler)
importScripts('https://www.gstatic.com/firebasejs/5.8.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/5.8.2/firebase-messaging.js');
var config = {
messagingSenderId: 'SENDER_ID'
};
firebase.initializeApp(config);
let messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
return self.registration.showNotification('title', {body: 'message'});
});
And in my App.vue (neither have I ever seen the console log in onMessage)
created() {
this.$messaging.onMessage(function(payload) {
console.log('Message received: ', payload);
// ...
});
},
methods: {
sendNotif() {
this.$messaging.requestPermission().then(() => this.$messaging.getToken())
.then((token) => {
console.log(token) // Receiver Token to use in the notification
})
.catch(function(err) {
console.log("Unable to get permission to notify.", err);
});
},
},
I can access the token, none of my configuration is wrong or else the postman request wouldn't give success. I've checked out several other questions related to this but no success so far...

Data is not captured in firestore react native

I'm using firestore with react native like below, but while running my app data is not added to the cloud. am not sure why, please help me to understand the actual problem here.
componentWillMount() {
console.log('Test1');
firebase.initializeApp({
apiKey: 'xxxxxxx',
authDomain: 'testing-8ex763xxxxxxxxxxxxxx',
databaseURL: 'https://testing-8e76xxxo.com',
projectId: 'testing-xxxxx',
storageBucket: 'testing-8xxxxx.com',
messagingSenderId: '73664xxx042'
});
firebase.firestore().enablePersistence()
.then(function() {
// Initialize Cloud Firestore through firebase
var db = firebase.firestore();
console.log('Test3', db);
db.collection('us').add({
first: 'hai',
last: '111',
born: 1815
})
.then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
})
.catch(function(err) {
if (err.code == 'failed-precondition') {
// Multiple tabs open, persistence can only be enabled
// in one tab at a a time.
// ...
} else if (err.code == 'unimplemented') {
// The current browser does not support all of the
// features required to enable persistence
// ...
}
});
}
You have not given the reference of doc.
And also use 'set' instead of add method.
db.collection('us').doc('some_name').set({
first: 'hai',
last: '111',
born: 1815
})

Web Push Notification FCM on Mobile

I'm trying to send push notification to users in my Web App but it is not working on mobile.
I'm using VueJs + Firebase, I use a Cloud Function to send the notification and in the service worker, I receive and handle for show to the user.
It works in the Browser on PC, but don't work in mobile 'Android', here are some code:
Cloud Function:
}).then(function (aTokens) {
const payload = {
data: {
title: 'Test-Title',
body: 'Test-Body'
}
}
// Send notifications to all tokens.
return admin.messaging().sendToDevice(aTokens, payload).then(res => {
res.results.forEach((result, index) => {
const error = result.error
if (error) {
console.error('Failure sending notification to', tokens[index], error)
}
})
response.send('OK')
})
})
Service-Worker Function:
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase- messaging.js');
var config = {
messagingSenderId: "123456789"
}
firebase.initializeApp(config);
var messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
var title = payload.data.title;
var options = {
body: payload.data.body
};
return self.registration.showNotification(title, options);
});
In Browser the Notification work See The Image:
But in Android it doesn't work, I have the last version or chrome and firefox and I tested in both, I also put the Web app in the home screen and allowed to send notification too. But the notifications never show there.
What I need to include for I see push notifications on mobile too?

Meteor accounts-google Token Expires

I have the Accounts-UI config setup to store an offline token for google thusly:
if (Meteor.isClient) {
Accounts.ui.config({
requestOfflineToken: { google: true },
forceApprovalPrompt: { google: true },
requestPermissions: { google: ["https://mail.google.com/"] }
});
}
However, tokens seem to expire. I assume I need to somehow use the refreshToken. I'm not sure how though with meteor. Any help would be lovely. Thanks!
I recommend using Google API Node JS client to refresh your access tokens.
https://github.com/google/google-api-nodejs-client/
It's available as a server-side NPM package, so you might want to use this package to be able to npmRequire it in your Meteor app.
Use this packages.json config to load the latest googleapis package :
{
"googleapis": "2.1.5"
}
Then in your Meteor server code you'll be able to refresh the access tokens like this :
ES2015
const GoogleApis = Meteor.npmRequire('googleapis');
function getAccessToken(user) {
const googleService = user.services.google;
// is token still valid for the next minute ?
if (googleService.expiresAt < Date.now() + 60 * 1000) {
// then just return the currently stored token
return {
access_token: googleService.accessToken,
token_type: 'Bearer',
id_token: googleService.idToken,
expiry_date: googleService.expiresAt,
refresh_token: googleService.refreshToken,
};
}
// fetch google service configuration
const googleServiceConfig = Accounts.loginServiceConfiguration.findOne({
service: 'google',
});
// declare an Oauth2 client
const oauth2Client = new GoogleApis.auth.OAuth2(googleServiceConfig.clientId, googleServiceConfig.secret);
// set the Oauth2 client credentials from the user refresh token
oauth2Client.setCredentials({
refresh_token: user.services.google.refreshToken,
});
// declare a synchronous version of the oauth2Client method refreshing access tokens
const refreshAccessTokenSync = Meteor.wrapAsync(oauth2Client.refreshAccessToken, oauth2Client);
// refresh tokens
const tokens = refreshAccessTokenSync();
// update the user document with the fresh token
Meteor.users.update(user._id, {
$set: {
'services.google.accessToken': tokens.access_token,
'services.google.idToken': tokens.id_token,
'services.google.expiresAt': tokens.expiry_date,
'services.google.refreshToken': tokens.refresh_token,
},
});
//
return tokens;
}
Here is a full example of how to refresh your access tokens before using a google service.
function listMeteorChannel() {
// fetch a user you want to act on behalf who authorized offline access
const user = Meteor.users.findOne({
'services.google.refreshToken': {
$exists: true,
},
});
if (!user) {
return;
}
const googleServiceConfig = Accounts.loginServiceConfiguration.findOne({
service: 'google',
});
// declare oauth2 client and set credentials
const oauth2Client = new GoogleApis.auth.OAuth2(googleServiceConfig.clientId, googleServiceConfig.secret);
// get user access token
const tokens = getAccessToken(user);
oauth2Client.setCredentials(tokens);
// obtain the youtube service at version 3 and perform authentication at service level
const youtube = GoogleApis.youtube({
version: 'v3',
auth: oauth2Client,
});
// declare a synchronous version of youtube.channels.list
const youtubeChannelsListSync = Meteor.wrapAsync(youtube.channels.list, youtube.channels);
// fetch an info snippet from the Meteor official YouTube channel
const result = youtubeChannelsListSync({
part: 'snippet',
// Meteor channel ID
id: 'UC3fBiJrFFMhKlsWM46AsAYw',
});
result.items.forEach((item) => {
// display the channel title, which should be 'Meteor'
console.log(item.snippet.title);
});
}
Meteor.startup(listMeteorChannel);

Categories

Resources