Angular Project: How to get instance of secondary firebase app? - javascript

In my angular app I have the same problem as the person who asked the following question:
Firebase kicks out current user
I want to be able to add a new user account without the current user (= the admin who is creating the new user account) being kicked out.
Apparently, this is possible by creating a second auth reference and use that to create users (see approved answer to the question linked to above):
var config = {apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com"};
var secondaryApp = firebase.initializeApp(config, "Secondary");
secondaryApp.auth().createUserWithEmailAndPassword(em, pwd).then(function(firebaseUser) {
console.log("User " + firebaseUser.uid + " created successfully!");
//I don't know if the next statement is necessary
secondaryApp.auth().signOut();
});
Following this answer, I tried the following:
registerUser(authData: AuthData, participantId: string, role: string): Promise<any> {
let config = {
apiKey: "API-Key",
authDomain: "myApp-a7211.firebaseapp.com",
databaseURL: "https://myApp-a7211.firebaseio.com",
};
let secondaryApp = firebase.initializeApp(config, "Secondary");
return secondaryApp.auth().createUserWithEmailAndPassword(authData.email, authData.password)
.then(function(firebaseUser) {
console.log("User " + firebaseUser + " created successfully!");
secondaryApp.auth().signOut();
});
}
The problem is that this works only once. After that, initialisation of the secondary firebaseApp is not possible because it has been initialised already.
So I thought, rather than initialising the secondary app inside the registerUser()-method, maybe I should do something like that (in file app.module.ts):
But then how can I refer to the secondary firebaseApp in the code?
UPDATE:
Following the suggested answer by Frank van Puffelen, I did the following:
1.) In file app.module.ts:
2.) In file auth.service.ts:
export class AuthService implements OnDestroy {
private secondaryApp = firebase.app("Secondary");
//other code
registerUser(authData: AuthData): Promise<any> {
return this.secondaryApp.auth().createUserWithEmailAndPassword(authData.email, authData.password)
.then(function(firebaseUser) {
console.log("User " + firebaseUser + " created successfully!");
this.secondaryApp.auth().signOut();
});
}
//other methods
}
However, when trying to add a new user, I get the following error message:
UPDATE 2:
Frank van Puffelen pointed out a silly mistake I had made: the name I registered the app with, and the name used to look the app back up, did not match.
After correcting this, the error message disappeared.
However, the current user was still kicked out after creating a new account.
... What finally worked was the following:
(file auth.service.ts:)
export class AuthService implements OnDestroy {
//do not initialise the secondary app in app.module.ts but here:
private config = {
apiKey: "API-KEY",
authDomain: "myApp-a7211.firebaseapp.com",
databaseURL: "https://myApp-a7211.firebaseio.com",
};
private secondaryApp = firebase.initializeApp(this.config, "SecondaryApp");
//other code
registerUser(authData: AuthData): Promise<any> {
return this.secondaryApp.auth().createUserWithEmailAndPassword(authData.email, authData.password)
.then(function(firebaseUser) {
console.log("User " + firebaseUser + " created successfully!");
this.secondaryApp.auth().signOut();
});
}
//other methods
}

You can make secondaryApp global and then refer to it from elsewhere in your code. So something like:
let secondaryApp;
registerUser(authData: AuthData, participantId: string, role: string): Promise<any> {
let config = {
apiKey: "AIzaSyAY1TWvQtK0tDQWmRzoouRNZzAnf15RG_A",
authDomain: "myApp-a7211.firebaseapp.com",
databaseURL: "https://myApp-a7211.firebaseio.com",
};
secondaryApp = firebase.initializeApp(config, "Secondary");
In fact, I'd pull the entire configuration of the secondary app out into a global scope, since it is only supposed to run once. So:
let config = {
apiKey: "AIzaSyAY1TWvQtK0tDQWmRzoouRNZzAnf15RG_A",
authDomain: "myApp-a7211.firebaseapp.com",
databaseURL: "https://myApp-a7211.firebaseio.com",
};
let secondaryApp = firebase.initializeApp(config, "Secondary");
registerUser(authData: AuthData, participantId: string, role: string): Promise<any> {
return secondaryApp.auth().createUserWithEmailAndPassword(authData.email, authData.password)
.then(function(firebaseUser) {
...
});
}
You can always look up the FirebaseApp instance by its name. So in your casse:
let secondaryApp = firebase.app("Secondary");

Related

firebase is not being recognized in Unity webGL Build

I have set up a test project in order to test Firebase with unity webGL builds.
I have created a *.jslib plugin to keep my js functions in there :
mergeInto(LibraryManager.library, {
GetJSON: function (path, objectName, callback, fallback) {
var parsedPath = Pointer_stringify(path);
var parsedObjectName= Pointer_stringify(objectName);
var parsedCallback = Pointer_stringify(callback);
var parsedFallback = Pointer_stringify(fallback);
try{
firebase.database().ref(parsedPath).once('value').then(function(snapshot) {
window.unityInstance.SendMessage(parsedObjectName, parsedCallback , JSON.stringify(snapshot.val()));
});
} catch(error){
window.unityInstance.SendMessage(parsedObjectName, parsedFallback, "There was an error: " + error.message);
}
}
});
After building and running, I add my Firebase config snippet into the index.html file(I have hidden the actual keys on this snippet):
<script type="module">
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.8.1/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.8.1/firebase-analytics.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "key",
authDomain: "domain",
projectId: "id",
storageBucket: "bucket",
messagingSenderId: "senderID",
appId: "appId",
measurementId: "measurementId"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
</script>
In unity, I am testing this by calling the GetJSON function, and I have a callback, and a fallback method:
void Start()
{
text.text = "Start worked";
GetJSON(path: "example", gameObject.name, callback: "OnRequestSuccess", fallback: "OnRequestFailed");
}
public void OnRequestSuccess(string data)
{
text.color = Color.green;
text.text = data;
}
public void OnRequestFailed(string error)
{
text.color = Color.red;
text.text = error;
}
After I have built and run my webGL project, and updated the index.html file with the proper configurations, the text turns red (Which means the OnRequestFailed() was called) and it says: "There was an error: firebase is not defined". Which means, it does not recognize the firebase when I use it on the *.jslib plugin. Where should the firebase be defined exactly? Because I am defining it in my index.html, or at least I think so?

Web firebase.messaging().onMessage not fired, but background notification perfectly fired

I want to reload or trigger some event in foregrounf if push message is sent with firebase.messaging().onMessage, but it not fired. I'm using firebase.mesaging.sw.js with background notification and it works correctly what is wrong with my code?
firebase.js
const config = {
apiKey: "x",
projectId: "x",
storageBucket: "x",
messagingSenderId: "x"
};
firebase.initializeApp(config);
const msg = firebase.messaging()
msg.requestPermission()
.then(() => {
return msg.getToken()
})
.then((token) => {
})
.catch((err) => {
})
msg.onMessage(function(payload) {
alert("Foreground message fired!")
console.log(payload)
});
firebase.messaging.sw.js
importScripts("https://www.gstatic.com/firebasejs/7.0.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/7.0.0/firebase-messaging.js");
const config = {
apiKey: "x",
projectId: "x",
storageBucket: 'x',
messagingSenderId: "x"
};
firebase.initializeApp(config);
const msg = firebase.messaging()
msg.setBackgroundMessageHandler(function(payload) {
let options = {
body: payload.data.body,
icon: payload.data.icon
}
return self.registration.showNotification(payload.data.title, options);
});
I don't know what is wrong with my code
Simple solution to this is update your Firebse to latest version.
Eg.
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js');
Note: Once you have updated your firebase libraries versions then messagingSenderId will not work in your firebase-messaging-sw.js file. You have to provide all other params eg. apiKey, projectId, appId along with messagingSenderId.
If still not work. Clean your browser cache and re-register service worker.
For more details you can refer to this solution
Still had the same issue in 2020. In my case it was like this:
you need to have same versions in importScripts for background messages and in your app for foreground messages
call it after obtaining token for background service
firebaseApp.messaging().getToken().then((currentToken) => {
if (currentToken) {
console.log(currentToken)
} else {
// Show permission request.
console.log(
'No Instance ID token available. Request permission to generate one.')
}
/** When app is active */
firebase.messaging().onMessage((payload) => {
console.log(payload)
}, e => {
console.log(e)
})
})
For anyone else with this problem, I finally solved it by:
Upgrading the Firebase SDK version in both header-included JS files and the SW JS file to latest (currently, that would be 7.8.1).
Adding the entire firebaseConfig array to the SW firebase.initializeApp(), as the previous answer suggests.
Cleaning the Chrome cache from the Application > Clear Storage section in the Developer Tools.
Deleting the previous registration token from my database.
Blocking and unblocking notifications from the browser to force a new token generation.
Basically, a total fresh start with updated Firebase SDK seems to fix issues like this.
You are missing lots of things and onMessage will only work if firebase is initialized before calling it. Please follow this. I have done it like this and it is working.
initialize firebase and get the token
export class BrowserFcmProvider {
export const FIREBASE_CONFIG = {
apiKey: "****",
authDomain: "****",
databaseURL: "****",
projectId: "****",
storageBucket: "****",
messagingSenderId: "****",
appId: "****"
}
firebase.initializeApp(FIREBASE_CONFIG);
async webGetToken() {
try {
const messaging = firebase.messaging();
await messaging.requestPermission();
const token = await messaging.getToken();
let uuidTemp = new DeviceUUID().get();
return this.saveTokenToFireStoreFromWeb(token, uuidTemp)
} catch (e) {
console.log(e);
}
}
saveTokenToFireStoreFromWeb(token, uuid) {
try {
const docData = {
token: token,
device_type: 'web',
uuid: uuid
}
const devicesRef = this.db.collection('devices')
return devicesRef.doc(uuid).set(docData);
} catch (e) {
console.log(e, 'saveTokenError');
}
}
showMessage() {
try {
const messaging = firebase.messaging();
messaging.onMessage((payload) => {
console.log(payload);
})
} catch (e) {
console.log(e)
}
}
}
And calling the method while app loads like this
async configureFirebaseForBrowser(res) {
await this.bfcm.webGetToken();
this.bfcm.showMessage();
}
Firebase function and payload type
const payloadWeb = {
title: title,
body: body,
data: {
title: title,
body: body
},
tokens: uniqueDevicesTokenArrayWeb,
}
const responseWeb = await admin.messaging().sendMulticast(payloadWeb);
console.log(responseWeb.successCount + ' notifications has been sent to Web successfully');
I have used async and await as we need to manage firebase/firestore operations asynchronously.
fcm does not work in Incognito mode and safari browser
Same issue i was faced. In my case firebase version in "package.json" and "firebase-messaging-sw.js" importScripts version was different. After set same version in "firebase-messaging-sw.js" importScripts which was in
"package.json", my issue is resolved.
Before change
**"package.json"**
"firebase": "^8.2.1",
**"firebase-messaging-sw.js"**
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.8.0/firebase-messaging.js');
After change
**"package.json"**
"firebase": "^8.2.1",
**"firebase-messaging-sw.js"**
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-messaging.js');

firebase - Create user with email and password returns undefined uid

I'm currently working on a function in firebase that creates users without logging them in, following a tutorial here on this website. (I decided not to follow the firebase-admin way of adding users due to lack of time). My current problem is when i execute the CreateUserWithEmailAndPassword method, it's promise does not work, and does not give a uid at all. The users are also not registering at all. Here is my code used for this:
var otherApp = firebase.initializeApp({
apiKey: "AIzaSyDXS11uOZGDmHYuN3J8BJxOG_9vanNakqA",
authDomain: "pasigueno-assist-1532249634197.firebaseapp.com",
databaseURL: "https://pasigueno-assist-1532249634197.firebaseio.com",
projectId: "pasigueno-assist-1532249634197",
storageBucket: "pasigueno-assist-1532249634197.appspot.com",
messagingSenderId: "394982410129"
}, "other");
otherApp.auth().createUserWithEmailAndPassword(username, password).then(function (user) {
var uid = user.uid;
var fullnames = fullname.value;
var barangays = barangay.value;
var status = "Active";
var addresss = address.value;
var userTypes = userType.value;
var rootRef = firebase.database().ref();
var storesRef = rootRef.child('users');
var newStoreRef = storesRef.push();
newStoreRef.set({
Address: addresss,
Name: fullnames,
Barangay: barangays,
Username: username,
UserType: userTypes,
UserID: uid,
Status: status
});
otherApp.auth().signOut();
console.log("ok");
}, function (error) {
console.log(error);
otherApp.auth().signOut();
});
var otherApp works as my secondary ref to avoid being kicked out of firebase when signing in regularly.
So, what kind of object do you get from that createUserWithEmailAndPassword call? It tells you, you get a UserCredential - which does not have a uid property. (However it has a user property that has your uid field).
Short answer:
otherApp.auth().createUserWithEmailAndPassword(username, password).then(function (userCreds) {
var uid = userCreds.user.uid;
// etc

Vue.Js with Firebase cloud firestore, adding items to database is triggered twice

I want to send an Item to my database collection in firestore, for some reason the add() function gets executed twice so the same object is sent two times with different autogenerated Id, which is obviously not the desired behavior, below is the file from which I initialize my firebase app.
import firebase from 'firebase'
// Initialize Firebase
var config = {
apiKey: "**********",
authDomain: "*******",
databaseURL: "https://*****.firebaseio.com",
projectId: "my-****",
storageBucket: "****.appspot.com",
messagingSenderId: "*******"
};
const firebaseApp = firebase.initializeApp(config);
firebaseApp.firestore().settings({ timestampsInSnapshots: true })
export default firebase.firestore()
now this code below is how i trigger the add() function to send the item to the database from my .vue file
import db from '../firebase/init.js';
export default {
...
methods: {
addNewItem(){
let item = {
row1: 'record one,
row2: 'record two,
}
db.collection('myItems').push(item)
.then(doc => console.log(doc))
.catch(err => console.log(err))
}
}
}
please let me know in a comment below if any additional information is needed for better clarifying the issue. thanks in advance.

Firebase cloud message/notifications are not receiving. JS

I am trying to send FCM to my react app using cloud functions.
Cloud function is executing, but notification is not being received on client side.
Here cloud function code.
exports.sendPush = functions.database.ref('/settings2').onWrite(event => {
let projectStateChanged = false;
let projectCreated = false;
let projectData = event.data.val();
if (!event.data.previous.exists()) {
projectCreated = true;
}
if (!projectCreated && event.data.changed()) {
projectStateChanged = true;
}
let msg = 'A project state was changed';
if (projectCreated) {
msg = `The following new project was added to the project: ${projectData.title}`;
}
tokens.push("fIGxxxxGtDGxxxx DEVICE Token");
let payload = {
notification: {
title: 'Firebase Notification',
body: 'This Is Message',
sound: 'default',
badge: '1'
}
};
return admin.messaging().sendToDevice(tokens, payload);
});
Here is the log of Cloud function
And here is code on my client side:
messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
// ...
});
There are not any errors, but nothing is in console. Do I have to do something with service worker file?
Any help would be appreciated.
There was an issue with my firebase-messaging-sw.js file. I have resolved this by following code.
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 = {
apiKey: "AIzaSyDtg4aQMQW67Jla1nUzrTTSEhVqpUeqKXI",
authDomain: "payxxxxxxx.firebaseapp.com",
databaseURL: "https://pxyxxxxx.firebaseio.com",
projectId: "pxxoll-pxxxs-fxxx",
storageBucket: "pxxx-pxxx-fxxxx1.apxxxot.com",
messagingSenderId: "2xxxx5xxx"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
For anyone new that may run across this post and are having issues with this especially if you copied and pasted something from online make sure you check the importScripts version and make sure its the same version as in your package.json file.
Example
Currently this package version is 8.3.1
so update
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
to
importScripts('https://www.gstatic.com/firebasejs/8.3.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.3.1/firebase-messaging.js');

Categories

Resources