Set up "firebase javascript" to use with "ionic serve" - node.js

I want to use Firebase Javascript, in an Ionic 2 project so I can develop the Push Notification logic that I want to apply, and test it in a browser, by using the CLI "ionic serve".
I've followed the step as explain in the doc under node.js / ES2015:
I did a CLI "npm install --save firebase" to add it to my project.
And then at the top of one of my project service I did:
import [regular Ionic 2 and Angular 2 import stuffs];
import * as firebase from 'firebase';
#Injectable()
export class PushNotifService {
constructor(private platform:Platform){
console.log("PushNotifService starts");
console.info(this.platform);
console.info(firebase);
}
}
I ran into the problem described in that SO thread.
I've tried then a different approach, by importing the file "https://www.gstatic.com/firebasejs/3.6.10/firebase.js", then I added it to [my project]/src/assets/js/firebase.js.
In [my project]/src/index.html i added:
<body>
<ion-app></ion-app>
<script src="assets/js/firebase.js"></script>
</body>
And in my service:
import [regular Ionic 2 and Angular 2 import stuffs];
declare var firebase: any;
#Injectable()
export class PushNotifService {
constructor(private platform:Platform){
console.log("PushNotifService starts");
console.info(this.platform);
console.info(firebase);
}
}
It does not work, it seems that the <script src="assets/js/firebase.js"></script> [my project]/src/index.html is not taken into account (it is not there when looking at the DOM with the Chrome console).
Any idea how to import the "https://www.gstatic.com/firebasejs/3.6.10/firebase.js" file without usin "npm install"?

SOME UPDATES:
In the ionic 2 project there is [my project]/src/index.html and [my project]/www/index.html. I was editing [my project]/src/index.html and changes after "bundles update" while "ionic serve" runs in command prompt did not apply on [my project]/www/index.html.
Now I've updated [my project]/www/index.html with:
<body>
<ion-app></ion-app>
<script src="assets/js/firebase.js"></script>
//or <script src="https://www.gstatic.com/firebasejs/3.6.10/firebase.js"></script>)
</body>
And it does work with service:
import [regular Ionic 2 and Angular 2 import stuffs];
declare var firebase: any;
#Injectable()
export class PushNotifService {
constructor(private platform:Platform){
console.log("PushNotifService starts");
console.info(this.platform);
console.info(firebase);
}
}
Afterwards I had to apply what is explained here:
I created a "firebase-messaging-sw.js" empty file in "[my project]/www/".
And finally, as it is explained here, "[my project]/www/firebase-messaging-sw.js" must contain:
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': 'YOUR SENDER ID'
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
NB: I've detailed the steps that had caused me troubles thru the implementation, beside that getToken() or onMessage() from
firebase.messaging.Messaging managed to work in my PushNotifService class once those other things around were in place. I didn't detail the server side (PHP script to send messages or Firebase project settings).

Related

Storing firebase config in .env files

I have a Sveltekit project where I am using firebase for authentication. I am storing the firebase.js file which contains the config parameters like apiKey and authDomain in the \src\lib folder. I am storing the apiKey value in the .env file which is present at the root of the project and using the process.env.API_KEY to load the value for the same. However when I do npm run build I get an error in the browser console - "process is not defined". I tried the below approaches but none of them seem to work -
Approach 1 -
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
import { config } from 'dotenv'
config()
const firebaseConfig = {
apiKey: process.env.API_KEY,
authDomain: process.env.AUTH_DOMAIN,
}
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)
export default auth
Approach 2 -
Here I used the env-cmd library which I found via another Stackoverflow post. Below is the updated code
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
const firebaseConfig = {
apiKey: process.env['API_KEY'],
authDomain: process.env['AUTH_DOMAIN'],
}
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)
export default auth
I also updated the scripts in package.json like below -
"scripts": {
"dev": "env-cmd vite dev",
"build": "env-cmd vite build",
"package": "svelte-kit package",
"preview": "vite preview",
"prepare": "svelte-kit sync"
}
Neither of the approaches seem to work and I still get the same error i.e. "process is not defined". Even some of the other repos I checked on Github had the apiKey hard coded in the config file, which obviously is a bad practice, even for hobby projects.
Any ideas on how I could incorporate the firebase apiKey via the .env file?
From the firebase docs
Unlike how API keys are typically used, API keys for Firebase services are not used to control access to backend resources; that can only be done with Firebase Security Rules (to control which users can access resources) and App Check (to control which apps can access resources).
Usually, you need to fastidiously guard API keys (for example, by using a vault service or setting the keys as environment variables); however, API keys for Firebase services are ok to include in code or checked-in config files.
Your .env file should have variables like this VITE_SECURE_API_KEY=API-KEY
and you can use them in your client-side app using import.meta.env.VITE_SECURE_API_KEY.
dotenv works on the server-side for sveltekit using node-adapter, also the firebase-admin package works only on the node environment.

React, Web3.js & Metaplex: Unable to import `programs.metadata.Metadata` from #metaplex/js

Issue
Attempting to follow the 'your first request' example here: https://docs.metaplex.com/sdk/js/getting-started#your-first-request
The module referred to in the examples doesn't contain the data needed.
For context, I am using this example to develop the solution explained at step 5 of these instructions: https://gist.github.com/creativedrewy/9bce794ff278aae23b64e6dc8f10e906
Steps to replicate
Step 1) I install the #metaplex/js package via: yarn add #metaplex/js
Step 2) I import programs from the module by placing import { programs } from '#metaplex/js';.
Step 3) I attempt to unpack Metadata from programs via: const { Metadata } = programs.metadata;
At this stage, if I execute npm run start or yarn run start I see the error that the property Metadata of programs.metadata is undefined. When I look in node_modules/#metaplex/js/ I see that the error is correct.
The only mention of metadata in the module is the function used to lookup metadata once you have the URL. The stage I am at is attempting to retrieve the URL, so this package is not useful, despite being the only one referred to in the docs.
To solve the issue, I created an empty react app and added the following dependencies to my package.json file:
"#metaplex/js": "^1.1.1",
"#solana/spl-token": "^0.1.8",
"#solana/web3.js": "^1.24.1",
I then ran npm install inside the app's root directory.
Inside App.js (or index.js if you did not use create-react-app), I unpacked Metadata directly from the metaplex package with the following line, placed at the top of the file:
import { Metadata } from '#metaplex/js';
Beneath all the imports, I added the following code (an edited version of the code from the example in the original question):
const connection = new Connection('devnet');
const tokenPublicKey = 'Gz3vYbpsB2agTsAwedtvtTkQ1CG9vsioqLW3r9ecNpvZ';
const run = async () => {
try {
const ownedMetadata = await Metadata.load(connection, tokenPublicKey);
console.log(ownedMetadata);
} catch {
console.log('Failed to fetch metadata');
}
};
In my implementation, I'm using a button inside my App() function, instead of calling run() directly like in the example:
<button
onClick={run}
>
GALLERY
</button>
Now, when clicking the button, I correctly see the metadata JSON displayed in the console.

Angular2 integration to core file system and node.js libraries

I am studying Angular2, Typescript and reactive programming.
I wrote a simple Typescript application on NodeJs which monitors a directory for changes (core OS and file system). In a single file.
Here it is https://github.com/maroshi/nodejs-directory-monitor/blob/master/app.ts
Now I want to add an interactive GUI to it using Angular2.
I want to integrate my directory monitor as service to Angular2 application.
The questions.
Is it architecturally safe/correct to allow Angular2 application to access the file system and OS (assuming it is a fancy NodeJs server)?
How to integrate NodeJs fs utility library into an Angular2 application.
I am using the Angular2 quickstart template from https://github.com/angular/quickstart.
I modified the app.component.ts
import * as FileSystem from 'fs';
import { Component, OnInit } from '#angular/core';`
#Component({
selector: 'my-app',
template: `
<h1>My First Angular 2 App</h1>
<p>Some FileSystem info: {{dirInfo}}</p>
`
})
export class AppComponent implements OnInit {
private proccesInfo: string;
ngOnInit(){
let tmpString: string[] = FileSystem.readdirSync('/home');
this.dirInfo = tmpString != null ? tmpString[0] : 'undefined';
}
}
This compiles well but fails to bootstrap with the following errors:
GET XHR http://localhost:3000/fs 404 (Not Found)
Error: patchProperty/desc.set/wrapFn#http://localhost:3000/node_moduleszone.js/dist/zone.js:769:27
Zone</ZoneDelegate</ZoneDelegate.prototype.invokeTask#http://localhost:3000/node_modules/zone.js/dist/zone.js:356:24
Zone</Zone</Zone.prototype.runTask#http://localhost:3000/node_modules/zone.js/dist/zone.js:256:29
ZoneTask/this.invoke#http://localhost:3000/node_modules/zone.js/dist/zone.js:423:29
Error loading http://localhost:3000/fs as "fs" from http://localhost:3000/app/app.component.js
Please advise about this exploration.
Note the tsconfig.json is the default tsconfig.json from the link above. Compiling for NodeJs
"module": "commonjs",
Thanks
Joy and happiness
Dudi

How to start Angular2 app under a sub forlder

By follow Angular2 example, I create my first app
under my project folder. I can run: "npm start" to make the application running
For example I can access the app from http://localhost:3000
I have a new requirement which I need to run the application under a context path, which mean I need to access the application through http://localhost:3000/myapp
The question is how to deploy or run Angular2 application in a sub folder path?
try to add in the index.html file. However, it seems Angular cannot resolve the path to find the template URL and resource JS and TS files.
Can anyone help to make sure I can run the app under a context path "myapp"?
Add base tag to index.html:
<base href="/myapp">
or in your bootstrap file (main.js)
import { provide } from '#angular/core';
import { APP_BASE_HREF } from '#angular/common';
bootstrap(AppComponent, [
provide(APP_BASE_HREF, {useValue: '/myapp'}),
]);

Render react component on node server, with webpack

I have a react component. <myFooter>. It is a simple footer.
import React from 'react';
import './my-footer.scss';
export default class myFooter extends React.Component {
render() {
return (
<footer className="col-xs-12">
hello !
</footer>
);
}
}
I want to render it from the server-side. On the backend, I have an express server. For that I wrote this:
import myFooter from '../components/my-footer.jsx';
app.get('/footer', function(req, res) {
var string1 = ReactDOMServer.renderToString(myFooter);
res.send(string1);
});
Now the problem is that server cannot read sass files. For client side rendering, I am using webpack. Webpack builds everything and gives a bundle file.
But i'm not sure what happens if its the server side. How can I compile using webpack. If I can, will i need to compile my app for each request on node server ?
You need 2 webpack builds:
1 to build the client
1 to build the server.
When building the server, use css-loader/locals instead of css-loader in your webpack configuration.
Read through this issue for more details: https://github.com/webpack/css-loader/issues/59

Resources