#firebasejs
Explore tagged Tumblr posts
Photo
Simple page application. Web app.
Hey awesome designers,
Looking to build a simple web app?
Then you're in right place. A simple web app example , using Vue + vuetifyjs + App + firebase.
Download link ( more instructions you will find in a link )- https://github.com/janisrozenfelds/Vue-Vuetifyjs-Firebase -- Get free high-quality photos Unsplash!
My Dribbble
#vuejs#vue#javascript#cod#github#github repository#vuetifyjs#firebase#firebasejs#janis rozenfelds#html5#html#css#vuetiify#app#web app#source code#source
0 notes
Text
VueJS & Firebase Cloud Firestore Stripped-Back - Tutorial Part 2
In this tutorial series we are using a stripped-back approach to getting started with Vuejs & Firebase Cloud Firestore to build full-stack web applications. No CLIs or build tools just a HTML page.
Putting the ‘C’ in CRUD
Welcome back to our Vue and Firebase stripped back tutorial. If you skipped part 1 of this tutorial you can get it here.
Let’s start straightaway from where we left off in part 1 and start looking at how we can develop our employee tracker app, EmployeeMagic, to let the user add records to their employee database. This represents the C in CRUD (Create, Read, Update, Delete).
We’ll start by adding some input boxes to our template for the user to be able to add employees. The fields we want are first and last names, job title, department and age.
Let’s start by adding a First Name field.
<body>
<div id=“app”>
<div v-bind:style=“mainStyle”>
<h1>{{ appTitle }}</h1>
<label>First Name</label> <input type=“text” v-model=“firstName”>
</div>
</div>
</body>
Notice the input element, we’ve added a Vue directive to it called v-model and we’ve assigned it a value of firstName. For AngularJS devs this will seem very familiar. v-model is a data binding directive that binds the input element to a variable in our view model (the data in the Vue Instance Object). Therefore whatever value the user keys into the input box will be automatically assigned to a variable in your Vue Instance Object. Now we don’t presently have a firstName variable in data in our Instance Object so we need to add it and assign it an initial value, in this case an empty string.
<script> var app = new Vue({ el : '#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, firstName : ‘’ } }) </script>
Just to prove that our data-binding in Vue is working and is in fact working in both directions (from the template to the Instance Object and from the Instance Object to the template), also called two-way data binding, we’ll stick a double-curly on the end of the input box eg
<input type=“text” v-model=“firstName”>{{ firstName }}
Save the file and refresh the page in your browser. As you begin to type in the First Name box, the name is displayed at the side of it. The input is assigning it to the firstName variable (via the v-model directive) and Vue is watching for changes in the firstName variable and when it detects one it changes anywhere in the page where firstName has a binding, in this case via the double-curly.
OK, enough of the fun and games, let’s add our other fields to the template and create their corresponding variables in the data section. As we’re grouping several fields together to form an employee we’ll change it to put them all in their own object called employee and change the template to bind the input boxes to the relevant properties on the employee object instead. We’ve proved our point with the two-way data binding for now so we’ll remove our double curly.
<body>
<div id=“app”>
<div v-bind:style=“mainStyle”>
<h1>{{ appTitle }}</h1>
<label>First Name</label> <input type=“text” v-model=“employee.firstName”></br>
<label>Last Name</label> <input type=“text” v-model=“employee.lastName”></br>
<label>Job Title</label> <input type=“text” v-model=“employee.jobTitle”></br>
<label>Dept.</label> <input type=“text” v-model=“employee.dept”></br>
<label>Age</label> <input type=“number” v-model:number=“employee.age”></br>
</div>
</div>
</body>
Notice that on the Age input we’ve added an extra command to the v-model directive, :number. This is very useful in Vue as, although the type of the input is set to number so the user cannot input anything other than valid numbers, by default when the value is converted by the binding to Vue data properties, it is converted as a string. As we want the age property to remain a number type, the v-model:number directive is required. <script> var app = new Vue({ el : '#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } } }) </script> We’ll next add a Save button which will write the entered employee to the database. To carry out the task of saving when the user clicks the Save button we need to hook the button into our Vue Instance Object and call a function that’s run to save our new employee record. To do this we need to use another Vue directive called v-on:click
<label>Age</label> <input type=“number” v-model:number=“employee.age”></br>
<button v-on:click=“saveEmployee()”>Save</button>
</div>
</div>
</body>
v-on is used to handle events and the :click is the specific event to be triggered on. We then assign the function that we want to run once the event (click) is triggered, in this case saveEmployee().
If you remember, in part 1 of this tutorial we mentioned that when using the v-bind directive along with a colon-command that you could use shorthand instead by dropping the v-bind eg v-bind:style could be entered as just :style for short. The same applies to the v-on directive however as it’s an event, rather than using the colon, you must use a @ instead. Therefore instead of using v-on:click you could use the shorthand version which is @click. Ultimately it’s a matter of preference and usually I would use the shorthand but to provide full explanations in these tutorials we’ll stick to using the verbose style.
We now need to write our saveEmployee() click handler function. This involves declaring functions or methods in our Vue Instance Object which you can do by declaring a new first-level object on the Instance Object called methods. All of your logic for our app will live in functions declared in Vue’s methods object. <script> var app = new Vue({ el : '#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } }, methods : { saveEmployee : function() { alert(‘You have saved ‘ + this.employee.firstName + ‘ ‘ + this.employee.lastName) } } }) </script> So, you can see that we’ve declared a saveEmployee function within the top-level methods object. In the above we’re not saving anything, we’re just going to display a standard alert message which includes displaying the last name and first name of the employee we’re saving. Notice that we’re using this to refer to our employee properties. Any variable declared in the data object of our Instance Object that we want to reference in our methods must be referenced using this, otherwise Vue won’t recognise it. As anyone who has worked with Javascript for any length of time knows, using this can be problematic as what it points to can change depending on the context from where it was called. There are ways around using this which we’ll discuss later but we’ll just stick with it as it is for now. Save the file, refresh your browser and enter the details of an employee, click Save and you should see the alert message appear. We’re now at the point of needing to be able to physically save our new employee to our Firebase Cloud Firestore. To get started with this you just need a bog-standard Google account. If you’ve got a gmail account or use any of Google’s products where you need to log-in then you’ve got a Google account. If not then you’ll need to create one which you can do on the Firebase site. To get started go to the Firebase web-site (https://firebase.com) and click Go To Console. If you’re not signed in to your Google account or you don’t have one you’ll then be taken to the usual sign-in/sign-up pages to get going, otherwise you’ll be taken to the Firebase console. Click Add Project and enter a project name and select your region. Once in the main console click the Database option on the left. You’ll be given the option of Realtime Database or Cloud Firestore. Make sure you select Cloud Firestore. You’ll also be asked how you want the security level to be setup, make sure you select Development/Test mode otherwise you’ll have to start setting up security rules manually which are a whole other subject altogether. Your Cloud Firestore will then be setup, which might take a short while. Once your database is setup we don’t need to do anything else in the database console however we do need to grab the code and libraries for getting Firebase into our app. To do this click the Project Overview option on the left. In the Get Started page click on the option for Add Firebase to your web app. In the window that pops up you’ll see a code snippet, just click the Copy button. Go back to your editor and paste the code snippet below the closing </body> tag and above the VueJS CDN script tag as shown below : </body>
<script src="https://www.gstatic.com/firebasejs/4.9.1/firebase.js"></script> <script> // Initialize Firebase var config = { apiKey: "AIzaSyA0KlHuISpQL1F0XMWv1FfmtbaJQmPKwqQ", authDomain: "vuefire-da3bf.firebaseapp.com", databaseURL: "https://vuefire-da3bf.firebaseio.com", projectId: "vuefire-da3bf", storageBucket: "vuefire-da3bf.appspot.com", messagingSenderId: "1094070580435" }; firebase.initializeApp(config); </script> <script src="https://cdn.jsdelivr.net/npm/vue"></script><script> var app = new Vue({ The version of the Firebase CDN link above (4.9.1) is current at the time of writing (Feb 2018) but is likely to be different by the time you are reading this, always use the link copied from the Firebase page. This details in the config object are specific to my account and project and yours will certainly be different, make sure you keep the code exactly the same as the code snippet copied from your Firebase project. The code snippet from Firebase however doesn’t include a CDN for Cloud Firestore, this may well be due to it still being officially in beta at the time of writing and may well be included in the standard code snippet by the time you’re reading this so it’s worth checking. At this point in time however, we’ll need to add it manually and the best way to do it is just to copy the line for the firebase CDN link for firebase.js, paste it below it and change the new line from firebase.js to firebase-firestore.js as below : <script src="https://www.gstatic.com/firebasejs/4.9.1/firebase.js"></script> <script src="https://www.gstatic.com/firebasejs/4.9.1/firebase-firestore.js"></script> Save the page and refresh in Chrome with the Console open and make sure there are no errors displayed before proceeding and if there are check you have followed everything above correctly. We’ve now got our libraries for Cloud Firestore and the code snippet will initialise Firebase to enable you to utilise your newly created database. Now we have to let our Vue app know about it. What we need to do is to create a Firestore object within our Vue app when it first runs so it’s available to us throughout our app. To ensure that our Firestore object is created at the beginning during initialisation of our app, we need to utilise a lifecycle hook that Vue provides, called created. Lifecycle hooks are effectively events that occur during Vue’s internal processing of our Instance Object. Vue exposes these events to us so we can hook into them and carry out some tasks at that specific point in our Vue Instance Object’s processing lifecycle. With the created hook, we can attach the tasks we want to carry out when the Vue Instance Object is first created, which is exactly what we need to do to generate a Firestore object to ensure we can access the database throughout the app. We’ll first initialise an object in our data section called db that we’ll use to access Firestore. We’ll then include a created hook which is a function containing our initialisation code. In this case we just want to assign an object from Firestore that we can use :
<script> var app = new Vue({ el : ’#app’, data : { appTitle : ‘EmployeeMagic’, mainStyle : { ‘margin’ : ’20px’ }, employee : {firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 }, db : {} }, methods : { saveEmployee : function() { alert(‘You have saved ‘ + this.employee.firstName + ‘ ‘ + this.employee.lastName) } }, created : function() { this.db = firebase.firestore() } }) </script> We’re now plugged into our Firestore through our db object. It’s now fairly straightforward to save our data to Firestore. We use Firestore’s add() function to save our employee object which, as we covered earlier, is automatically populated through data binding when the user enters the information into the input boxes. To call add() we must tell Firestore which Collection to save the new object to. Collections in Firestore represent a formal declaration of the documents or objects we’re going to save. This makes it much more like the Tables and Records we’re used to in relational databases, where tables are collections and records are documents. In this case we’ll save it to a collection called Employees - note that we didn’t explicitly setup the Employees collection previously, it will be automatically created for us by Firestore if it doesn’t already exist. We’ll remove the alert from our saveEmployee function and replace it with the line to save the new employee. methods : { saveEmployee : function() { this.db.collection(‘Employees’).add(this.employee); } }, Again notice that we’re referencing db using this, as we are with employee (and all of our data properties). We’ll review this shortly but it’s important to note it for now. Save the file in your code editor and refresh it in Chrome. Enter the details of an employee and click Save. Nothing will appear to happen on the page, however open your Firebase console, select Database and you’ll see your new record under the Employees collection. Notice that the record has a strange looking unique Id automatically assigned to it, we’ll be utilising this in another part of the tutorial. Let’s tidy up the saving process. Firstly we want to make sure it doesn’t save unless something is entered into both the First and Last Name fields. Secondly we want some visual indication that you have saved to the database, specifically the input boxes are cleared ready for another new employee. In order to clear the employee inputs we’ll implement a separate function called clearEmployee() so we’re not cluttering up our save function. methods : { saveEmployee : function() { if ((this.employee.firstName) && (this.employee.lastName)) { this.db.collection(‘Employees’).add(this.employee) clearEmployee() } else alert(‘You must enter both a first and last name to save.’) }, clearEmployee : function() { this.employee = { firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } } }, Note 2-way data binding, changing the properties in the view model reflects in the input boxes that they’re bound to. It’s important to note that Firestore’s add() function is asynchronous so any code that comes after it, such as clearing the input fields, will be executed before it can be determined if the employee was saved correctly. Therefore rather than simply call the clearEmployee() function immediately after add() as we have done above, we’ll need to utilise the promise which Firestore’s add() function returns and put any code we want to execute after it’s successfully saved into the returned promise’s then(). saveEmployee : function() { if ((this.employee.firstName) && (this.employee.lastName)) this.db.collection(‘Employees’).add(this.employee) .then(function() { this.clearEmployee() }) .catch(function() { console.log(‘Error saving employee ‘ + this.employee.firstName + ‘ ‘ + this.employee.lastName) }) else alert(‘You must enter both a first and last name to save.’) }, Here we’ve chained a then() to the add() function call and passed in a function which calls the clearEmployee() to clear the properties for the input boxes only after we’re sure of a successful save. We’ve also chained a catch() so any saving errors are logged to the console.
A brief explain of Promises
If you’re not familiar with promises, they’re simply a way to handle asynchronous code. Asynchronous functions are just standard functions which carry out some processing but return control back to the caller before completing it’s process (to avoid blocking the app’s execution). Async functions usually return a promise object which enables the code which called the function to implement any tasks that needs to execute only after the async function has fully completed it’s process. In this instance we only want to clear the input boxes once we know that the employee has definitely saved. To do this we call then() which is a function on the returned promise object. then() accepts a function as a parameter which we use to execute any code we want after we know the save has completed, in this case to clear the employee properties and inputs. As we’ve done above you can also chain a call to the promise’s catch() function to execute any code should the async function not succeed. With all of that said, the new changes we’ve just made WILL NOT WORK!! And they will not work because of the this issue that was foretold. The reference to this changes depending on the context in which it was called. Therefore when we come to execute the code that is passed to the then() or catch() functions, this points to something else other than our Instance Object data and we’ll get errors! There are a couple of ways around this. The traditional way is to simply assign this at the beginning of a function to another variable, usually called that, and then reference that instead of this throughout the function to be sure that you’ll always reference the desired object. This works but it means you’re always having to remember to implement it at the beginning of every method. The other way is to reference the Instance Object explicitly where you know this won’t work for you. In this tutorial we declared a variable to contain our Vue Instance Object called app eg var app = new Vue({. You can therefore call app.clearEmployee() instead of this.clearEmployee() in the then() function and it would work. The problem is that context again gets in the way and you cannot use an explicit reference to the Instance Object in it’s own context so saying app.db.collection(‘Employees’).add(app.employee) in the main saveEmployee() function won’t work either, so you’d end up using this in some places and app in others.
The ideal solution would enable us to use one way throughout to refer to the properties and methods on your Instance Object to ensure consistency but without additional workload that you would need to remember to implement on each method. Fortunately ES6/ES2015 introduced arrow functions which help us resolve this problem. With arrow functions we can use an explicit reference to the Instance Object in every context throughout our methods. Arrow functions, from a declarative standpoint, simply change a function declaration from : function() { }
to () => { } So let’s change our saveEmployee() function from a standard function declaration to an arrow function and do the same with the then() and catch() functions. Then replace every reference of this to app. saveEmployee : () => { if ((app.employee.firstName) && (app.employee.lastName)) app.db.collection(‘Employees’).add(app.employee) .then(() => { app.clearEmployee() }) .catch(() => { console.log(‘Error saving employee ‘ + app.employee.firstName + ‘ ‘ + app.employee.lastName) }) else alert(‘You must enter both a first and last name to save.’) }, For consistency purposes we should also change our clearEmployee() method as well clearEmployee : () => { app.employee = { firstName : ‘’, lastName : ‘’, jobTitle : ‘’, dept : ‘’, age : 0 } } The only exception to this rule is the created lifestyle hook function where the VueJS docs expressly recommends not declaring it as an arrow function so we’ll leave it as a standard function declaration (including referencing this rather than app). Like with Promises, arrow functions are a fairly new addition to JS so you must be using an evergreen browser, like Chrome, which implements them natively otherwise you’ll need to use a transpiler such as Babel. We’ve now completed the Create task from our CRUD list. In this tutorial we’ve added input boxes and bound them to properties on our view model to create 2-way data binding. We’ve added events and methods to our Instance Object, created a Firebase Cloud Firestore project and hooked it into our app, covered Vue’s lifecycle hooks to initialise a reference to our database and then covered how to save employees to our Cloud Firestore. Finally we covered the issues with using this and how arrow functions can help us overcome these problems. In the next part of the tutorial we’ll cover the R in CRUD, Reading (or Retrieving) employees from our database. We’ll cover getting data back from our Firestore and explain how to implement realtime updates. I hope you’ll join me.
You can download the completed code for this part of the tutorial on Github using the repo below and select the part2 folder. https://github.com/MancDev/VueFire
1 note
·
View note
Text
How To Build Your Own Comment System Using Firebase
About The Author
Aman is a software developer and a student. He codes, writes, and runs a lot. He usually finds time to study when he is not doing any of those. More about Aman …
Ever wanted to have a comments section for your blog, but were overwhelmed by the high cost and maintenance solutions? Firebase can be your savior. In this guide, we’ll learn how to add a comments section to your blog with Firebase, while learning the basics of Firebase on the way.
A comments section is a great way to build a community for your blog. Recently when I started blogging, I thought of adding a comments section. However, it wasn’t easy. Hosted comments systems, such as Disqus and Commento, come with their own set of problems:
They own your data.
They are not free.
You cannot customize them much.
So, I decided to build my own comments system. Firebase seemed like a perfect hosting alternative to running a back-end server.
First of all, you get all of the benefits of having your own database: You control the data, and you can structure it however you want. Secondly, you don’t need to set up a back-end server. You can easily control it from the front end. It’s like having the best of both worlds: a hosted system without the hassle of a back end.
In this post, that’s what we’ll do. We will learn how to set up Firebase with Gatsby, a static site generator. But the principles can be applied to any static site generator.
Let’s dive in!
What Is Firebase?
Firebase is a back end as a service that offers tools for app developers such as database, hosting, cloud functions, authentication, analytics, and storage.
Cloud Firestore (Firebase’s database) is the functionality we will be using for this project. It is a NoSQL database. This means it’s not structured like a SQL database with rows, columns, and tables. You can think of it as a large JSON tree.
Introduction to the Project
Let’s initialize the project by cloning or downloading the repository from GitHub.
I’ve created two branches for every step (one at the beginning and one at the end) to make it easier for you to track the changes as we go.
Let’s run the project using the following command:
gatsby develop
If you open the project in your browser, you will see the bare bones of a basic blog.
(Large preview)
The comments section is not working. It is simply loading a sample comment, and, upon the comment’s submission, it logs the details to the console.
Our main task is to get the comments section working.
Before doing anything, let’s understand how the code for the comments section works.
Four components are handling the comments sections:
blog-post.js
Comments.js
CommentForm.js
Comment.js
First, we need to identify the comments for a post. This can be done by making a unique ID for each blog post, or we can use the slug, which is always unique.
The blog-post.js file is the layout component for all blog posts. It is the perfect entry point for getting the slug of a blog post. This is done using a GraphQL query.
export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `
Before sending it over to the Comments.js component, let’s use the substring() method to get rid of the trailing slash (/) that Gatsby adds to the slug.
const slug = post.fields.slug.substring(1, post.fields.slug.length - 1) return ( <Layout> <div className="container"> <h1>{post.frontmatter.title}</h1> <div dangerouslySetInnerHTML= /> <Comments comments={comments} slug={slug} /> </div> </Layout> ) }
The Comments.js component maps each comment and passes its data over to Comment.js, along with any replies. For this project, I have decided to go one level deep with the commenting system.
The component also loads CommentForm.js to capture any top-level comments.
const Comments = ({ comments, slug }) => { return ( <div> <h2>Join the discussion</h2> <CommentForm slug={slug} /> <CommentList> {comments.length > 0 && comments .filter(comment => !comment.pId) .map(comment => { let child if (comment.id) { child = comments.find(c => comment.id === c.pId) } return ( <Comment key={comment.id} child={child} comment={comment} slug={slug} /> ) })} </CommentList> </div> ) }
Let’s move over to CommentForm.js. This file is simple, rendering a comment form and handling its submission. The submission method simply logs the details to the console.
const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }
The Comment.js file has a lot going on. Let’s break it down into smaller pieces.
First, there is a SingleComment component, which renders a comment.
I am using the Adorable API to get a cool avatar. The Moment.js library is used to render time in a human-readable format.
const SingleComment = ({ comment }) => ( <div> <div className="flex-container"> <div className="flex"> <img src="https://api.adorable.io/avazars/65/[email protected]" alt="Avatar" /> </div> <div className="flex"> <p className="comment-author"> {comment.name} <span>says</span> </p> {comment.time} &&(<time>(moment(comment.time.toDate()).calendar()}</time>)} </div> </div> </p>{comment.content}</p> </div> )
Next in the file is the Comment component. This component shows a child comment if any child comment was passed to it. Otherwise, it renders a reply box, which can be toggled on and off by clicking the “Reply” button or “Cancel Reply” button.
const Comment = ({ comment, child, slug }) => { const [showReplyBox, setShowReplyBox] = useState(false) return ( <CommentBox> <SingleComment comment={comment} /> {child && ( <CommentBox child className=comment-reply"> <SingleComment comment={child} /> </CommentBox> )} {!child && ( <div> {showReplyBox ? ( <div> <button className="btn bare" onClick={() => setShowReplyBoy(false)} > Cancel Reply </button> <CommentForm parentId={comment.id} slug={slug} /> </div> ) : ( <button className="btn bare" onClick={() => setShowReplyBox(true)}> Reply </button> )} </div> )} </div> )} </CommentBox>
Now that we have an overview, let’s go through the steps of making our comments section.
1. Add Firebase
First, let’s set up Firebase for our project.
Start by signing up. Go to Firebase, and sign up for a Google account. If you don’t have one, then click “Get Started”.
Click on “Add Project” to add a new project. Add a name for your project, and click “Create a project”.
(Large preview)
Once we have created a project, we’ll need to set up Cloud Firestore.
In the left-side menu, click “Database”. Once a page opens saying “Cloud Firestore”, click “Create database” to create a new Cloud Firestore database.
(Large preview)
When the popup appears, choose “Start in test mode”. Next, pick the Cloud Firestore location closest to you.
(Large preview)
Once you see a page like this, it means you’ve successfully created your Cloud Firestore database.
(Large preview)
Let’s finish by setting up the logic for the application. Go back to the application and install Firebase:
yarn add firebase
Add a new file, firebase.js, in the root directory. Paste this content in it:
import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase
You’ll need to replace yourFirebaseConfig with the one for your project. To find it, click on the gear icon next to “Project Overview” in the Firebase app.
(Large preview)
This opens up the settings page. Under your app’s subheading, click the web icon, which looks like this:
(Large preview)
This opens a popup. In the “App nickname” field, enter any name, and click “Register app”. This will give your firebaseConfig object.
<!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.15.5/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.Google.com/docs/web/setup#available-libraries --> <script> // Your web app’s Firebase configuration var firebaseConfig = { ... }; // Initialize Firebase firbase.initializeApp(firebaseConfig); </script>
Copy just the contents of the firebaseConfig object, and paste it in the firebase.js file.
Is It OK to Expose Your Firebase API Key?
Yes. As stated by a Google engineer, exposing your API key is OK.
The only purpose of the API key is to identify your project with the database at Google. If you have set strong security rules for Cloud Firestore, then you don’t need to worry if someone gets ahold of your API key.
We’ll talk about security rules in the last section.
For now, we are running Firestore in test mode, so you should not reveal the API key to the public.
How to Use Firestore?
You can store data in one of two types:
collection A collection contains documents. It is like an array of documents.
document A document contains data in a field-value pair.
Remember that a collection may contain only documents and not other collections. But a document may contain other collections.
This means that if we want to store a collection within a collection, then we would store the collection in a document and store that document in a collection, like so:
{collection-1}/{document}/{collection-2}
How to Structure the Data?
Cloud Firestore is hierarchical in nature, so people tend to store data like this:
blog/{blog-post-1}/content/comments/{comment-1}
But storing data in this way often introduces problems.
Say you want to get a comment. You’ll have to look for the comment stored deep inside the blog collection. This will make your code more error-prone. Chris Esplin recommends never using sub-collections.
I would recommend storing data as a flattened object:
blog-posts/{blog-post-1} comments/{comment-1}
This way, you can get and send data easily.
How to Get Data From Firestore?
To get data, Firebase gives you two methods:
get() This is for getting the content once.
onSnapshot() This method sends you data and then continues to send updates unless you unsubscribe.
How to Send Data to Firestore?
Just like with getting data, Firebase has two methods for saving data:
set() This is used to specify the ID of a document.
add() This is used to create documents with automatic IDs.
I know, this has been a lot to grasp. But don’t worry, we’ll revisit these concepts again when we reach the project.
2. Create Sample Date
The next step is to create some sample data for us to query. Let’s do this by going to Firebase.
Go to Cloud Firestore. Click “Start a collection”. Enter comments for the “Collection ID”, then click “Next”.
(Large preview)
For the “Document ID”, click “Auto-ID. Enter the following data and click “Save”.
(Large preview)
While you’re entering data, make sure the “Fields” and “Types” match the screenshot above. Then, click “Save”.
That’s how you add a comment manually in Firestore. The process looks cumbersome, but don’t worry: From now on, our app will take care of adding comments.
At this point, our database looks like this: comments/{comment}.
Our sample data is ready to query. Let’s get started by getting the data for our blog.
Go to blog-post.js, and import the Firestore from the Firebase file that we just created.
import {firestore} from "../../firebase.js"
To query, we will use the useEffect hook from React. If you haven’t already, let’s import it as well.
useEffect(() => { firestore .collection(`comments`) .onSnapshot(snapshot => { const posts = snapshot.docs .filter(doc => doc.data().slug === slug) .map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) }, [slug])
The method used to get data is onSnapshot. This is because we also want to listen to state changes. So, the comments will get updated without the user having to refresh the browser.
We used the filter and map methods to find the comments whose slug matches the current slug.
One last thing we need to think about is cleanup. Because onSnapshot continues to send updates, this could introduce a memory leak in our application. Fortunately, Firebase provides a neat fix.
useEffect(() => { const cleanUp = firestore .doc(`comments/${slug}`) .collection("comments") .onSnapshot(snapshot => { const posts = snapshot.docs.map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) return () => cleanUp() }, [slug])
Once you’re done, run gatsby develop to see the changes. We can now see our comments section getting data from Firebase.
(Large preview)
Let’s work on storing the comments.
To store comments, navigate to the CommentForm.js file. Let’s import Firestore into this file as well.
import { firestore } from "../../firebase.js"
To save a comment to Firebase, we’ll use the add() method, because we want Firestore to create documents with an auto-ID.
Let’s do that in the handleCommentSubmission method.
firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })
First, we get the reference to the comments collection, and then add the comment. We’re also using the catch method to catch any errors while adding comments.
At this point, if you open a browser, you can see the comments section working. We can add new comments, as well as post replies. What’s more amazing is that everything works without our having to refresh the page.
(Large preview)
You can also check Firestore to see that it is storing the data.
(Large preview)
Finally, let’s talk about one crucial thing in Firebase: security rules.
5. Tighten Security Rules
Until now, we’ve been running Cloud Firestore in test mode. This means that anybody with access to the URL can add to and read our database. That is scary.
To tackle that, Firebase provides us with security rules. We can create a database pattern and restrict certain activities in Cloud Firestore.
In addition to the two basic operations (read and write), Firebase offers more granular operations: get, list, create, update, and delete.
A read operation can be broken down as:
get Get a single document.
list Get a list of documents or a collection.
A write operation can be broken down as:
create Create a new document.
update Update an existing document.
delete Delete a document.
To secure the application, head back to Cloud Firestore. Under “Rules”, enter this:
service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }
On the first line, we define the service, which, in our case, is Firestore. The next lines tell Firebase that anything inside the comments collection may be read and created.
If we had used this:
allow read, write;
… that would mean that users could update and delete existing comments, which we don’t want.
Firebase’s security rules are extremely powerful, allowing us to restrict certain data, activities, and even users.
Congrats! You have just seen the power of Firebase. It is such an excellent tool to build secure and fast applications.
We’ve built a super-simple comments section. But there’s no stopping you from exploring further possibilities:
Add profile pictures, and store them in Cloud Storage for Firebase;
Use Firebase to allow users to create an account, and authenticate them using Firebase authentication;
Use Firebase to create inline Medium-like comments.
A great way to start would be to head over to Firestore’s documentation.
Finally, let’s head over to the comments section below and discuss your experience with building a comments section using Firebase.
(ra, yk, al, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/how-to-build-your-own-comment-system-using-firebase/ source https://scpie.tumblr.com/post/627344381619372032
0 notes
Text
How To Build Your Own Comment System Using Firebase
About The Author
Aman is a software developer and a student. He codes, writes, and runs a lot. He usually finds time to study when he is not doing any of those. More about Aman …
Ever wanted to have a comments section for your blog, but were overwhelmed by the high cost and maintenance solutions? Firebase can be your savior. In this guide, we’ll learn how to add a comments section to your blog with Firebase, while learning the basics of Firebase on the way.
A comments section is a great way to build a community for your blog. Recently when I started blogging, I thought of adding a comments section. However, it wasn’t easy. Hosted comments systems, such as Disqus and Commento, come with their own set of problems:
They own your data.
They are not free.
You cannot customize them much.
So, I decided to build my own comments system. Firebase seemed like a perfect hosting alternative to running a back-end server.
First of all, you get all of the benefits of having your own database: You control the data, and you can structure it however you want. Secondly, you don’t need to set up a back-end server. You can easily control it from the front end. It’s like having the best of both worlds: a hosted system without the hassle of a back end.
In this post, that’s what we’ll do. We will learn how to set up Firebase with Gatsby, a static site generator. But the principles can be applied to any static site generator.
Let’s dive in!
What Is Firebase?
Firebase is a back end as a service that offers tools for app developers such as database, hosting, cloud functions, authentication, analytics, and storage.
Cloud Firestore (Firebase’s database) is the functionality we will be using for this project. It is a NoSQL database. This means it’s not structured like a SQL database with rows, columns, and tables. You can think of it as a large JSON tree.
Introduction to the Project
Let’s initialize the project by cloning or downloading the repository from GitHub.
I’ve created two branches for every step (one at the beginning and one at the end) to make it easier for you to track the changes as we go.
Let’s run the project using the following command:
gatsby develop
If you open the project in your browser, you will see the bare bones of a basic blog.
(Large preview)
The comments section is not working. It is simply loading a sample comment, and, upon the comment’s submission, it logs the details to the console.
Our main task is to get the comments section working.
Before doing anything, let’s understand how the code for the comments section works.
Four components are handling the comments sections:
blog-post.js
Comments.js
CommentForm.js
Comment.js
First, we need to identify the comments for a post. This can be done by making a unique ID for each blog post, or we can use the slug, which is always unique.
The blog-post.js file is the layout component for all blog posts. It is the perfect entry point for getting the slug of a blog post. This is done using a GraphQL query.
export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `
Before sending it over to the Comments.js component, let’s use the substring() method to get rid of the trailing slash (/) that Gatsby adds to the slug.
const slug = post.fields.slug.substring(1, post.fields.slug.length - 1) return ( <Layout> <div className="container"> <h1>{post.frontmatter.title}</h1> <div dangerouslySetInnerHTML= /> <Comments comments={comments} slug={slug} /> </div> </Layout> ) }
The Comments.js component maps each comment and passes its data over to Comment.js, along with any replies. For this project, I have decided to go one level deep with the commenting system.
The component also loads CommentForm.js to capture any top-level comments.
const Comments = ({ comments, slug }) => { return ( <div> <h2>Join the discussion</h2> <CommentForm slug={slug} /> <CommentList> {comments.length > 0 && comments .filter(comment => !comment.pId) .map(comment => { let child if (comment.id) { child = comments.find(c => comment.id === c.pId) } return ( <Comment key={comment.id} child={child} comment={comment} slug={slug} /> ) })} </CommentList> </div> ) }
Let’s move over to CommentForm.js. This file is simple, rendering a comment form and handling its submission. The submission method simply logs the details to the console.
const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }
The Comment.js file has a lot going on. Let’s break it down into smaller pieces.
First, there is a SingleComment component, which renders a comment.
I am using the Adorable API to get a cool avatar. The Moment.js library is used to render time in a human-readable format.
const SingleComment = ({ comment }) => ( <div> <div className="flex-container"> <div className="flex"> <img src="https://api.adorable.io/avazars/65/[email protected]" alt="Avatar" /> </div> <div className="flex"> <p className="comment-author"> {comment.name} <span>says</span> </p> {comment.time} &&(<time>(moment(comment.time.toDate()).calendar()}</time>)} </div> </div> </p>{comment.content}</p> </div> )
Next in the file is the Comment component. This component shows a child comment if any child comment was passed to it. Otherwise, it renders a reply box, which can be toggled on and off by clicking the “Reply” button or “Cancel Reply” button.
const Comment = ({ comment, child, slug }) => { const [showReplyBox, setShowReplyBox] = useState(false) return ( <CommentBox> <SingleComment comment={comment} /> {child && ( <CommentBox child className=comment-reply"> <SingleComment comment={child} /> </CommentBox> )} {!child && ( <div> {showReplyBox ? ( <div> <button className="btn bare" onClick={() => setShowReplyBoy(false)} > Cancel Reply </button> <CommentForm parentId={comment.id} slug={slug} /> </div> ) : ( <button className="btn bare" onClick={() => setShowReplyBox(true)}> Reply </button> )} </div> )} </div> )} </CommentBox>
Now that we have an overview, let’s go through the steps of making our comments section.
1. Add Firebase
First, let’s set up Firebase for our project.
Start by signing up. Go to Firebase, and sign up for a Google account. If you don’t have one, then click “Get Started”.
Click on “Add Project” to add a new project. Add a name for your project, and click “Create a project”.
(Large preview)
Once we have created a project, we’ll need to set up Cloud Firestore.
In the left-side menu, click “Database”. Once a page opens saying “Cloud Firestore”, click “Create database” to create a new Cloud Firestore database.
(Large preview)
When the popup appears, choose “Start in test mode”. Next, pick the Cloud Firestore location closest to you.
(Large preview)
Once you see a page like this, it means you’ve successfully created your Cloud Firestore database.
(Large preview)
Let’s finish by setting up the logic for the application. Go back to the application and install Firebase:
yarn add firebase
Add a new file, firebase.js, in the root directory. Paste this content in it:
import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase
You’ll need to replace yourFirebaseConfig with the one for your project. To find it, click on the gear icon next to “Project Overview” in the Firebase app.
(Large preview)
This opens up the settings page. Under your app’s subheading, click the web icon, which looks like this:
(Large preview)
This opens a popup. In the “App nickname” field, enter any name, and click “Register app”. This will give your firebaseConfig object.
<!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.15.5/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.Google.com/docs/web/setup#available-libraries --> <script> // Your web app’s Firebase configuration var firebaseConfig = { ... }; // Initialize Firebase firbase.initializeApp(firebaseConfig); </script>
Copy just the contents of the firebaseConfig object, and paste it in the firebase.js file.
Is It OK to Expose Your Firebase API Key?
Yes. As stated by a Google engineer, exposing your API key is OK.
The only purpose of the API key is to identify your project with the database at Google. If you have set strong security rules for Cloud Firestore, then you don’t need to worry if someone gets ahold of your API key.
We’ll talk about security rules in the last section.
For now, we are running Firestore in test mode, so you should not reveal the API key to the public.
How to Use Firestore?
You can store data in one of two types:
collection A collection contains documents. It is like an array of documents.
document A document contains data in a field-value pair.
Remember that a collection may contain only documents and not other collections. But a document may contain other collections.
This means that if we want to store a collection within a collection, then we would store the collection in a document and store that document in a collection, like so:
{collection-1}/{document}/{collection-2}
How to Structure the Data?
Cloud Firestore is hierarchical in nature, so people tend to store data like this:
blog/{blog-post-1}/content/comments/{comment-1}
But storing data in this way often introduces problems.
Say you want to get a comment. You’ll have to look for the comment stored deep inside the blog collection. This will make your code more error-prone. Chris Esplin recommends never using sub-collections.
I would recommend storing data as a flattened object:
blog-posts/{blog-post-1} comments/{comment-1}
This way, you can get and send data easily.
How to Get Data From Firestore?
To get data, Firebase gives you two methods:
get() This is for getting the content once.
onSnapshot() This method sends you data and then continues to send updates unless you unsubscribe.
How to Send Data to Firestore?
Just like with getting data, Firebase has two methods for saving data:
set() This is used to specify the ID of a document.
add() This is used to create documents with automatic IDs.
I know, this has been a lot to grasp. But don’t worry, we’ll revisit these concepts again when we reach the project.
2. Create Sample Date
The next step is to create some sample data for us to query. Let’s do this by going to Firebase.
Go to Cloud Firestore. Click “Start a collection”. Enter comments for the “Collection ID”, then click “Next”.
(Large preview)
For the “Document ID”, click “Auto-ID. Enter the following data and click “Save”.
(Large preview)
While you’re entering data, make sure the “Fields” and “Types” match the screenshot above. Then, click “Save”.
That’s how you add a comment manually in Firestore. The process looks cumbersome, but don’t worry: From now on, our app will take care of adding comments.
At this point, our database looks like this: comments/{comment}.
Our sample data is ready to query. Let’s get started by getting the data for our blog.
Go to blog-post.js, and import the Firestore from the Firebase file that we just created.
import {firestore} from "../../firebase.js"
To query, we will use the useEffect hook from React. If you haven’t already, let’s import it as well.
useEffect(() => { firestore .collection(`comments`) .onSnapshot(snapshot => { const posts = snapshot.docs .filter(doc => doc.data().slug === slug) .map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) }, [slug])
The method used to get data is onSnapshot. This is because we also want to listen to state changes. So, the comments will get updated without the user having to refresh the browser.
We used the filter and map methods to find the comments whose slug matches the current slug.
One last thing we need to think about is cleanup. Because onSnapshot continues to send updates, this could introduce a memory leak in our application. Fortunately, Firebase provides a neat fix.
useEffect(() => { const cleanUp = firestore .doc(`comments/${slug}`) .collection("comments") .onSnapshot(snapshot => { const posts = snapshot.docs.map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) return () => cleanUp() }, [slug])
Once you’re done, run gatsby develop to see the changes. We can now see our comments section getting data from Firebase.
(Large preview)
Let’s work on storing the comments.
To store comments, navigate to the CommentForm.js file. Let’s import Firestore into this file as well.
import { firestore } from "../../firebase.js"
To save a comment to Firebase, we’ll use the add() method, because we want Firestore to create documents with an auto-ID.
Let’s do that in the handleCommentSubmission method.
firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })
First, we get the reference to the comments collection, and then add the comment. We’re also using the catch method to catch any errors while adding comments.
At this point, if you open a browser, you can see the comments section working. We can add new comments, as well as post replies. What’s more amazing is that everything works without our having to refresh the page.
(Large preview)
You can also check Firestore to see that it is storing the data.
(Large preview)
Finally, let’s talk about one crucial thing in Firebase: security rules.
5. Tighten Security Rules
Until now, we’ve been running Cloud Firestore in test mode. This means that anybody with access to the URL can add to and read our database. That is scary.
To tackle that, Firebase provides us with security rules. We can create a database pattern and restrict certain activities in Cloud Firestore.
In addition to the two basic operations (read and write), Firebase offers more granular operations: get, list, create, update, and delete.
A read operation can be broken down as:
get Get a single document.
list Get a list of documents or a collection.
A write operation can be broken down as:
create Create a new document.
update Update an existing document.
delete Delete a document.
To secure the application, head back to Cloud Firestore. Under “Rules”, enter this:
service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }
On the first line, we define the service, which, in our case, is Firestore. The next lines tell Firebase that anything inside the comments collection may be read and created.
If we had used this:
allow read, write;
… that would mean that users could update and delete existing comments, which we don’t want.
Firebase’s security rules are extremely powerful, allowing us to restrict certain data, activities, and even users.
Congrats! You have just seen the power of Firebase. It is such an excellent tool to build secure and fast applications.
We’ve built a super-simple comments section. But there’s no stopping you from exploring further possibilities:
Add profile pictures, and store them in Cloud Storage for Firebase;
Use Firebase to allow users to create an account, and authenticate them using Firebase authentication;
Use Firebase to create inline Medium-like comments.
A great way to start would be to head over to Firestore’s documentation.
Finally, let’s head over to the comments section below and discuss your experience with building a comments section using Firebase.
(ra, yk, al, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/how-to-build-your-own-comment-system-using-firebase/
0 notes
Text
How To Build Your Own Comment System Using Firebase
About The Author
Aman is a software developer and a student. He codes, writes, and runs a lot. He usually finds time to study when he is not doing any of those. More about Aman …
Ever wanted to have a comments section for your blog, but were overwhelmed by the high cost and maintenance solutions? Firebase can be your savior. In this guide, we’ll learn how to add a comments section to your blog with Firebase, while learning the basics of Firebase on the way.
A comments section is a great way to build a community for your blog. Recently when I started blogging, I thought of adding a comments section. However, it wasn’t easy. Hosted comments systems, such as Disqus and Commento, come with their own set of problems:
They own your data.
They are not free.
You cannot customize them much.
So, I decided to build my own comments system. Firebase seemed like a perfect hosting alternative to running a back-end server.
First of all, you get all of the benefits of having your own database: You control the data, and you can structure it however you want. Secondly, you don’t need to set up a back-end server. You can easily control it from the front end. It’s like having the best of both worlds: a hosted system without the hassle of a back end.
In this post, that’s what we’ll do. We will learn how to set up Firebase with Gatsby, a static site generator. But the principles can be applied to any static site generator.
Let’s dive in!
What Is Firebase?
Firebase is a back end as a service that offers tools for app developers such as database, hosting, cloud functions, authentication, analytics, and storage.
Cloud Firestore (Firebase’s database) is the functionality we will be using for this project. It is a NoSQL database. This means it’s not structured like a SQL database with rows, columns, and tables. You can think of it as a large JSON tree.
Introduction to the Project
Let’s initialize the project by cloning or downloading the repository from GitHub.
I’ve created two branches for every step (one at the beginning and one at the end) to make it easier for you to track the changes as we go.
Let’s run the project using the following command:
gatsby develop
If you open the project in your browser, you will see the bare bones of a basic blog.
(Large preview)
The comments section is not working. It is simply loading a sample comment, and, upon the comment’s submission, it logs the details to the console.
Our main task is to get the comments section working.
Before doing anything, let’s understand how the code for the comments section works.
Four components are handling the comments sections:
blog-post.js
Comments.js
CommentForm.js
Comment.js
First, we need to identify the comments for a post. This can be done by making a unique ID for each blog post, or we can use the slug, which is always unique.
The blog-post.js file is the layout component for all blog posts. It is the perfect entry point for getting the slug of a blog post. This is done using a GraphQL query.
export const query = graphql` query($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { html frontmatter { title } fields { slug } } } `
Before sending it over to the Comments.js component, let’s use the substring() method to get rid of the trailing slash (/) that Gatsby adds to the slug.
const slug = post.fields.slug.substring(1, post.fields.slug.length - 1) return ( <Layout> <div className="container"> <h1>{post.frontmatter.title}</h1> <div dangerouslySetInnerHTML= /> <Comments comments={comments} slug={slug} /> </div> </Layout> ) }
The Comments.js component maps each comment and passes its data over to Comment.js, along with any replies. For this project, I have decided to go one level deep with the commenting system.
The component also loads CommentForm.js to capture any top-level comments.
const Comments = ({ comments, slug }) => { return ( <div> <h2>Join the discussion</h2> <CommentForm slug={slug} /> <CommentList> {comments.length > 0 && comments .filter(comment => !comment.pId) .map(comment => { let child if (comment.id) { child = comments.find(c => comment.id === c.pId) } return ( <Comment key={comment.id} child={child} comment={comment} slug={slug} /> ) })} </CommentList> </div> ) }
Let’s move over to CommentForm.js. This file is simple, rendering a comment form and handling its submission. The submission method simply logs the details to the console.
const handleCommentSubmission = async e => { e. preventDefault() let comment = { name: name, content: content, pId: parentId ∣∣ null, time: new Date(), } setName("") setContent("") console.log(comment) }
The Comment.js file has a lot going on. Let’s break it down into smaller pieces.
First, there is a SingleComment component, which renders a comment.
I am using the Adorable API to get a cool avatar. The Moment.js library is used to render time in a human-readable format.
const SingleComment = ({ comment }) => ( <div> <div className="flex-container"> <div className="flex"> <img src="https://api.adorable.io/avazars/65/[email protected]" alt="Avatar" /> </div> <div className="flex"> <p className="comment-author"> {comment.name} <span>says</span> </p> {comment.time} &&(<time>(moment(comment.time.toDate()).calendar()}</time>)} </div> </div> </p>{comment.content}</p> </div> )
Next in the file is the Comment component. This component shows a child comment if any child comment was passed to it. Otherwise, it renders a reply box, which can be toggled on and off by clicking the “Reply” button or “Cancel Reply” button.
const Comment = ({ comment, child, slug }) => { const [showReplyBox, setShowReplyBox] = useState(false) return ( <CommentBox> <SingleComment comment={comment} /> {child && ( <CommentBox child className=comment-reply"> <SingleComment comment={child} /> </CommentBox> )} {!child && ( <div> {showReplyBox ? ( <div> <button className="btn bare" onClick={() => setShowReplyBoy(false)} > Cancel Reply </button> <CommentForm parentId={comment.id} slug={slug} /> </div> ) : ( <button className="btn bare" onClick={() => setShowReplyBox(true)}> Reply </button> )} </div> )} </div> )} </CommentBox>
Now that we have an overview, let’s go through the steps of making our comments section.
1. Add Firebase
First, let’s set up Firebase for our project.
Start by signing up. Go to Firebase, and sign up for a Google account. If you don’t have one, then click “Get Started”.
Click on “Add Project” to add a new project. Add a name for your project, and click “Create a project”.
(Large preview)
Once we have created a project, we’ll need to set up Cloud Firestore.
In the left-side menu, click “Database”. Once a page opens saying “Cloud Firestore”, click “Create database” to create a new Cloud Firestore database.
(Large preview)
When the popup appears, choose “Start in test mode”. Next, pick the Cloud Firestore location closest to you.
(Large preview)
Once you see a page like this, it means you’ve successfully created your Cloud Firestore database.
(Large preview)
Let’s finish by setting up the logic for the application. Go back to the application and install Firebase:
yarn add firebase
Add a new file, firebase.js, in the root directory. Paste this content in it:
import firebase from "firebase/app" import "firebase/firestore" var firebaseConfig = 'yourFirebaseConfig' firebase.initializeApp(firebaseConfig) export const firestore = firebase.firestore() export default firebase
You’ll need to replace yourFirebaseConfig with the one for your project. To find it, click on the gear icon next to “Project Overview” in the Firebase app.
(Large preview)
This opens up the settings page. Under your app’s subheading, click the web icon, which looks like this:
(Large preview)
This opens a popup. In the “App nickname” field, enter any name, and click “Register app”. This will give your firebaseConfig object.
<!-- The core Firebase JS SDK is always required and must be listed first --> <script src="https://www.gstatic.com/firebasejs/7.15.5/firebase-app.js"></script> <!-- TODO: Add SDKs for Firebase products that you want to use https://firebase.Google.com/docs/web/setup#available-libraries --> <script> // Your web app’s Firebase configuration var firebaseConfig = { ... }; // Initialize Firebase firbase.initializeApp(firebaseConfig); </script>
Copy just the contents of the firebaseConfig object, and paste it in the firebase.js file.
Is It OK to Expose Your Firebase API Key?
Yes. As stated by a Google engineer, exposing your API key is OK.
The only purpose of the API key is to identify your project with the database at Google. If you have set strong security rules for Cloud Firestore, then you don’t need to worry if someone gets ahold of your API key.
We’ll talk about security rules in the last section.
For now, we are running Firestore in test mode, so you should not reveal the API key to the public.
How to Use Firestore?
You can store data in one of two types:
collection A collection contains documents. It is like an array of documents.
document A document contains data in a field-value pair.
Remember that a collection may contain only documents and not other collections. But a document may contain other collections.
This means that if we want to store a collection within a collection, then we would store the collection in a document and store that document in a collection, like so:
{collection-1}/{document}/{collection-2}
How to Structure the Data?
Cloud Firestore is hierarchical in nature, so people tend to store data like this:
blog/{blog-post-1}/content/comments/{comment-1}
But storing data in this way often introduces problems.
Say you want to get a comment. You’ll have to look for the comment stored deep inside the blog collection. This will make your code more error-prone. Chris Esplin recommends never using sub-collections.
I would recommend storing data as a flattened object:
blog-posts/{blog-post-1} comments/{comment-1}
This way, you can get and send data easily.
How to Get Data From Firestore?
To get data, Firebase gives you two methods:
get() This is for getting the content once.
onSnapshot() This method sends you data and then continues to send updates unless you unsubscribe.
How to Send Data to Firestore?
Just like with getting data, Firebase has two methods for saving data:
set() This is used to specify the ID of a document.
add() This is used to create documents with automatic IDs.
I know, this has been a lot to grasp. But don’t worry, we’ll revisit these concepts again when we reach the project.
2. Create Sample Date
The next step is to create some sample data for us to query. Let’s do this by going to Firebase.
Go to Cloud Firestore. Click “Start a collection”. Enter comments for the “Collection ID”, then click “Next”.
(Large preview)
For the “Document ID”, click “Auto-ID. Enter the following data and click “Save”.
(Large preview)
While you’re entering data, make sure the “Fields” and “Types” match the screenshot above. Then, click “Save”.
That’s how you add a comment manually in Firestore. The process looks cumbersome, but don’t worry: From now on, our app will take care of adding comments.
At this point, our database looks like this: comments/{comment}.
Our sample data is ready to query. Let’s get started by getting the data for our blog.
Go to blog-post.js, and import the Firestore from the Firebase file that we just created.
import {firestore} from "../../firebase.js"
To query, we will use the useEffect hook from React. If you haven’t already, let’s import it as well.
useEffect(() => { firestore .collection(`comments`) .onSnapshot(snapshot => { const posts = snapshot.docs .filter(doc => doc.data().slug === slug) .map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) }, [slug])
The method used to get data is onSnapshot. This is because we also want to listen to state changes. So, the comments will get updated without the user having to refresh the browser.
We used the filter and map methods to find the comments whose slug matches the current slug.
One last thing we need to think about is cleanup. Because onSnapshot continues to send updates, this could introduce a memory leak in our application. Fortunately, Firebase provides a neat fix.
useEffect(() => { const cleanUp = firestore .doc(`comments/${slug}`) .collection("comments") .onSnapshot(snapshot => { const posts = snapshot.docs.map(doc => { return { id: doc.id, ...doc.data() } }) setComments(posts) }) return () => cleanUp() }, [slug])
Once you’re done, run gatsby develop to see the changes. We can now see our comments section getting data from Firebase.
(Large preview)
Let’s work on storing the comments.
To store comments, navigate to the CommentForm.js file. Let’s import Firestore into this file as well.
import { firestore } from "../../firebase.js"
To save a comment to Firebase, we’ll use the add() method, because we want Firestore to create documents with an auto-ID.
Let’s do that in the handleCommentSubmission method.
firestore .collection(`comments`) .add(comment) .catch(err => { console.error('error adding comment: ', err) })
First, we get the reference to the comments collection, and then add the comment. We’re also using the catch method to catch any errors while adding comments.
At this point, if you open a browser, you can see the comments section working. We can add new comments, as well as post replies. What’s more amazing is that everything works without our having to refresh the page.
(Large preview)
You can also check Firestore to see that it is storing the data.
(Large preview)
Finally, let’s talk about one crucial thing in Firebase: security rules.
5. Tighten Security Rules
Until now, we’ve been running Cloud Firestore in test mode. This means that anybody with access to the URL can add to and read our database. That is scary.
To tackle that, Firebase provides us with security rules. We can create a database pattern and restrict certain activities in Cloud Firestore.
In addition to the two basic operations (read and write), Firebase offers more granular operations: get, list, create, update, and delete.
A read operation can be broken down as:
get Get a single document.
list Get a list of documents or a collection.
A write operation can be broken down as:
create Create a new document.
update Update an existing document.
delete Delete a document.
To secure the application, head back to Cloud Firestore. Under “Rules”, enter this:
service cloud.firestore { match /databases/{database}/documents { match /comments/{id=**} { allow read, create; } } }
On the first line, we define the service, which, in our case, is Firestore. The next lines tell Firebase that anything inside the comments collection may be read and created.
If we had used this:
allow read, write;
… that would mean that users could update and delete existing comments, which we don’t want.
Firebase’s security rules are extremely powerful, allowing us to restrict certain data, activities, and even users.
Congrats! You have just seen the power of Firebase. It is such an excellent tool to build secure and fast applications.
We’ve built a super-simple comments section. But there’s no stopping you from exploring further possibilities:
Add profile pictures, and store them in Cloud Storage for Firebase;
Use Firebase to allow users to create an account, and authenticate them using Firebase authentication;
Use Firebase to create inline Medium-like comments.
A great way to start would be to head over to Firestore’s documentation.
Finally, let’s head over to the comments section below and discuss your experience with building a comments section using Firebase.
(ra, yk, al, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/how-to-build-your-own-comment-system-using-firebase/ source https://scpie1.blogspot.com/2020/08/how-to-build-your-own-comment-system.html
0 notes
Link
どうも、親からもらったお年玉でマッチングアプリを始めるも、いいね 0 件のまま 3 ヶ月で退会した@sadnessOjisan です。 今日はタイトルの通り、マッチングアプリ強者を体験できる PWA を開発します。具体的には、いいね 通知がたくさん届くアプリを開発します。なおこのアプリは「通知止まらん www」を体験できるアプリを作ったの影響を深く受けました。ただし、これから作る push 通知体験アプリでは、通知の疑似体験ではなく本当に通知が届きます シンプルにプッシュを送るだけのコード: https://github.com/sadnessOjisan/simple-push マッチングアプリ っぽいUIがついたコード: https://github.com/sadnessOjisan/simple-push-ui 書いた動機 この記事では Firebase を使った web push 通知を行う方法について、なるべく周辺知識に触れながら、解説を行っていきます。はじめて push 通知を行いたい人が、全体感を掴むと同時に、実際に手を動かして push 通知を送信できるようになる記事を目指しています。 どうしてこの記事を書いているかで言うと、いま現在(2019 年 7 月)、インターネット上に転がっている情報を集めながら開発していると、web push 通知機能について混乱を引き起こす可能性があり、情報を整理しておきたかったからです。その混乱の理由としては次の 3 つが挙げられます。 いまはサポートされていないサービスや規格について言及している記事の SEO パワーが強い push を送る方法が 1 通りではなく、誤った方法の組み合わせをしてしまう可能性がある push を行えるサービス(たとえば Firebase)の概念なのか、web push 通知そのものに関する概念のものかが分からない ex) VAPID, FCM, GCM, gcm_sender_id, APNs, Push Server, Push Service など ちなみに私は、はじめてweb push通知機能を実装する際、「web push 通知」でググったページだけで開発を試みましたが、動かなかったです。その後に Firebase のチュートリアルも行いましたが、自分で push 通知を送ることはできなかったです。 そこでこの記事では、push 通知について解説し、Firebase をどう使えば良いかを、なるべく写真やコードを示しながら、手を動かして学べるようにしました。 push 通知の仕組み そもそも push 通知ってなんでしょうか? スマホやブラウザを操作していると、上からひょこってなんか出てきますよね。それが push 通知でしょうか。 半分合っていて、半分間違っています。それはプッシュ通知そのものではなく、ただの通知とも呼べるからです。 なぜならサーバーから Push しなくても通知は出せるからです。たとえばアラーム機能などがそうです。 そのため、push 通知機能は、 サーバーから push された通知を受け取る機能 その受け取った通知をユーザーに表出させる機能 からなると捉えると良いでしょう。 この感覚は、後々デバッグするときに知っておくと役に立ちます。 たとえば、サーバーからの push に失敗しているのか、通知に失敗しているのかの切り分けができるようになります。 また切り分け観点では、iOS/Android アプリに通知を出すことと、ブラウザに通知を出すことも全然違うことを意識しておいてください。規格や利用できるツールからして��きく異なります。そのためweb push通知について調べる際はiOSやAndroidの情報に気をつけてください。(「push通知」ではなく「web push通知」と言う言葉で検索すると良いと思います。) 1 そこで次の節からは、iOS/Android に送る push 通知とブラウザに送る web push 通知について解説します。 iOS/Android にどう送るか iOS/Android への push 通知は、この記事で主として取り扱いたい内容ではないので、プッシュ通知の基礎知識&秒間 1 万を超えるプッシュ通知基盤のアーキテクチャと仕組みとは (1/2)をまるっと引用した文章で説明します。 プッシュ通知は iOS デバイスに対してはアップルの「APNs(Apple Push Notification Service)」、Android デバイスに対してはグーグルの「GCM(Google Cloud Messaging)」を利用して実現します。 細かな違いはあるものの APNs・GCM 共に基本的な考え方は同じで、プッシュ通知を実現するためには以下の 2 つの機能を保つ必要があります。 デバイス情報の登録機能 プッシュ通知の配信機能 プッシュ通知は APNs・GCM に対して「対象アプリ」と「対象デバイス」を指定してメッセージを送る必要があります。「アプリ」については APNs・GCM からアプリごとに認証キーが発行されるため、それを保持しておけばよいのですが、問題は「デバイス」です。 デバイスを指定するためにはデバイストークン(GCM の場合は登録 ID に当たりますがデバイストークンに用語を統一)という情報を必要とします。デバイストークンはデバイス内でアプリから APNs・GCM に通信をしないと取得できません。 プッシュ通知を行うためにはデバイス情報を自分たちで管理する必要があるため、アプリ内でデバイストークンを取得した後に自分たちのサーバーに送信して格納しておく必要があります プッシュ通知を配信するには、APNs・GCM に対して基本的には「認証キー」「デバイストークン」「メッセージ」を送る必要があります。これによりデバイストークンとひも付いた実端末に配信が行われます ここで注目したい言葉は APNs と GCM(いまは FCM に統一されています。) です。これらはそれぞれ、Apple と Google が管理している push 通知のためのサービスです。 ちなみに FCM のようなサービスを提供しているプラットフォームは Firebase だけではありません。いわゆる (m)BaaS を提供しているサービスであればサポートしているところもあるでしょう。たとえば、Azure にはNotification Hubsがあり、国内においても nifty がニフクラ mobile backendを提供しています。 また、これらのサービスに頼らずとも、APNs や GCM をそのまま使ったりもできます。その場合は自力で push 通知配信基盤を開発することとなります。メルカリ社は Gaurun といったライブラリを提供しており、配信基盤の開発を行うことができます。 web push 通知の仕組み 次に web push 通知を出す方法を解説します。 web push 通知は、 iOS/Android に対する通知と比べ、規格からまったく異なります。 web push 通知を行う際には、APNs や FCM といったサービスは不要です。ではどのようにして push 通知をしているのでしょうか。 それはブラウザそのものに web push を受け取れる機能を用意し、各ブラウザベンダーが提供している push server(push service とも呼ばれている)が push 通知をブラウザに送ります。��して、そのブラウザに備わっている Service Worker が、web push 通知をユーザーに通知しています。この仕組みは今の所、Google Chrome, Edge, Firefox, Android Chrome が対応しています。 web push 通知は、 push server を発火させる pushserver が serviceworker にメッセージを送る serviceworker が通知を出す といった順序で行われます。 そしてこれも混乱の原因なのですが、ここでいう push server は Firebase のようなサービスをさすのではなく、各ブラウザベンダーが提供している push 用のサーバーやサービスを差します。 そのような push server を利用するための方法や規格としてweb-push-protocol があります。この規格に則って、その push server を利用すれば push 通知は送れます。また、web-pushのようなライブラリを利用すると、この規格に沿った開発も比較的簡単に行えます。ただ、この方法は各ブラウザベンダーごとに実装を作る必要があり、少々苦労があります。 そこで、最近は mozilla が採用していた VAPID(Voluntary Application Server Identification for Web Push) という仕組みを各ブラウザベンダーが採用したことを受け、この VAPID に則った実装によって全ブラウザ共通の通知機能を開発します。 VAPID はアプリケーションサーバーが作った JWT を Push サーバーが検証し、検証に成功したら Push を送る仕組みのことです。この仕組みによりシンプルにさまざまなブラウザーに web push 通知を送れるようになりました。 さらには Firebase(FCM) がこの VAPID という仕組みに対応したことで、FCM を利用してサポートブラウザすべてに通知を送れるようになりました。これまでは FCM 経由で、Google Chrome に push を通知するためには gcm_sender_id というものをアプリケーション(manifest.json)で明示する必要がありましたが、VAPID を使える今は不要になりました。(ただし古いブラウザー(v51 未満)をサポートする場合は必要です。) Firebase が VAPID に対応したことにより、iOS や Android だけでなく Web にも通知を送れるようになりました。そのような背景があり、push 通知 = Firebase のような認識も持たれ始め、Firebase の用語と web push 通知の用語が混在して、自分が勉強したときに混乱したのだなと思っております。 次の章では、そんな便利な Firebase の使い方を紹介します。 Firebase から web push 通知を送ってみよう Firebase を設定する Firebase の初期設定を行います。 まずプロジェクトを作成しましょう。 Firebase を利用するには、Firebase から提供されている SDK が必要です。 その SDK には config が必要であり、ここではその設定情報を取得します。 取得しないといけない設定項目は、 const firebaseConfig = { apiKey: FIREBASE_API_KEY, authDomain: `${FIREBASE_PROJECT_ID}.firebaseapp.com`, projectId: FIREBASE_PROJECT_ID, messagingSenderId: FIREBASE_SENDER_ID }; です。すべて Settings に入っています。 FIREBASE_API_KEY は「ウェブ API キー」、FIREBASE_PROJECT_ID は「プロジェクト ID 」、FIREBASE_SENDER_ID はクラウドメッセージングタブの「送信者 ID」です。これらはどこかに控えておきましょう。 また、クラウドメッセージングタブにある、ウェブプッシュ証明書から鍵ペアを発行し、これも保存しておいてください。これは VAPID キー というもので、実際に通知を送るときに必要になるものです。 さきの VAPID の説明に当てはめるなら、JWT の検証に必要となる公開鍵です。 ここで気をつけたいことは、これから Firebase の Firebase Cloud Messaging というサービスを利用するわけですが、サイ��バーにあるそれは利用しません。 このページに遷移すると Cloud Messaging 機能について解説されているのですが、web push 通知への導線がありません。結論から言うと、このサービスは今回は使わなくてもいいのですが、久しぶりに Firebase を使う場合などに混乱するかもしれないので気をつけておきましょう。 service worker を準備する。 web push 通知では、通知の受け取りは service worker 経由で行います。その service worker を設定しましょう。 firebase-messaging-sw.js という名のファイルをプロジェクトルートに設置しましょう。 そしてこれを JS で、navigator.serviceWorker.register('path/to/file')を実行し、サービスワーカーとして登録します。 と言いたいところなんですが、Firebase SDK を利用する場合はアプリケーションのルートに firebase-messaging-sw.js を設置しておくと、Firebase SDK(firebase-messaging.js)がこのファイルを自動的に読み取り、サービスワーカーとして登録してくれます。2 その、firebase-messaging.js の中身は次の通りです。ちょっとした解説やつまづきそうなポイントはコメントに書いています。 // importScriptsはservice worker内から他のserviceworkerを読み込むときに使えます importScripts("https://www.gstatic.com/firebasejs/6.2.4/firebase-app.js"); importScripts("https://www.gstatic.com/firebasejs/6.2.4/firebase-messaging.js"); firebase.initializeApp({ messagingSenderId: "11111111111" }); const messaging = firebase.messaging(); /** * background時の通知の扱い。ここではconsoleにメッセージを出力した上で、通知を出している。通知の中身はtitleやoptionから設定できる。 */ messaging.setBackgroundMessageHandler(function(payload) { console.log( "[firebase-messaging-sw.js] Received background message ", payload ); var notificationTitle = "ONIAI"; var notificationOptions = { body: "あなたのプロフィールがイイねされました", // 通知の右にでる画像 icon: "", }; return self.registration.showNotification( notificationTitle, notificationOptions ); }); /** * foreground時にメッセージを受け取ると、通知をする。通知の中身はtitleやoptionから設定できる。 */ self.addEventListener("push", function(event) { const title = "ONIAI"; const options = { body: "あなたのプロフィールがイイねされました", // 通知の右にでる画像 icon: "", // 通知の左にでる画像 badge: "" }; event.waitUntil(self.registration.showNotification(title, options)); }); ここまでくれば、Service Worker から ブラウザに通知を送ることができます。 適当な HTML ファイルと一緒に Firebase Hosting などにアップロードして確かめてみましょう。[^2] コンソールを開き、Application タブを選択してください。そこに Push とういボタンがあるはずです。 それをクリックしましょう。おそらく通知が届いたかと思います。 push service から push 通知をブラウザに届ける それでは service worker からではなく、push server経由で通知を送ってみましょう。 まず Firebase の設定を行います。なお私の環境は TypeScript と webpack を利用して開発を行なっています。そのため Firebase の SDK は node module として DL しています。 そのため、webpack のようなモジュール間の依存解決を行う bunlder を利用しない場合は、CDN 経由で Firebase の SDK を読み込んでください。3 また、私は TypeScript で書いていますが、型注釈は入れていないので、コピペすれば普通の ES6 対応の JS 環境でも動くかと思います。 import * as firebase from "firebase/app"; import "firebase/messaging"; const FIREBASE_API_KEY = process.env.FIREBASE_API_KEY; const FIREBASE_PROJECT_ID = process.env.FIREBASE_PROJECT_ID; const FIREBASE_VAPID_KEY = process.env.FIREBASE_VAPID_KEY; const FIREBASE_SENDER_ID = process.env.FIREBASE_SENDER_ID; const firebaseConfig = { apiKey: FIREBASE_API_KEY, authDomain: `${FIREBASE_PROJECT_ID}.firebaseapp.com`, projectId: FIREBASE_PROJECT_ID, messagingSenderId: FIREBASE_SENDER_ID }; firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging(); confing にあるものは冒頭でメモしてもらった値です。私は .env として外部に書き出しているため、このような書き方になっていますが、直接書いてしまっても問題はないです。(どうせコンソール開かれたら見えてしまうものです。) これで Firebase Cloud Messaging(FCM) を使う準備が整いました。 そして次のコードをファイルに足しましょう。 messaging.usePublicVapidKey(FIREBASE_VAPID_KEY); messaging.onMessage(payload { console.log("Message received. ", payload); }); messaging .getToken() .then(currentToken { if (currentToken) { document.getElementById("token").textContent = currentToken; } else { console.log( "No Instance ID token available. Request permission to generate one." ); } }) .catch(err { console.log("An error occurred while retrieving token. ", err); }); messaging.usePublicVapidKey(FIREBASE_VAPID_KEY); で VAPID で利用する公開鍵を登録しています。 そしてmessaging.onMessage()でメッセージを受け取ったときの挙動を書いています。ここではメッセージ内容をコンソールに出力しています。ただし、実際に通知を受け取ってからブラウザに表出させる処理は、さきほど Service Worker に書いているので、この console 出力だけでもきちんと通知されるようになっています。 また、web push 通知をデバイスに届けるためには、配信する際にどのデバイスへ送るかを指定する必要があります。 その識別には token と読んでいるものを利用します。 messaging.getToken() では、そのトークンを取得し、その続くチェーンで token を画面に表示させています。この token を push を送るスクリプトや関数に読み込ませることで、端末を指定して web push 通知を送ることができます。 それでは、通知を送ってみましょう。Firebase を push service として利用する VAPID 方式の web push 通知では、ヘッダーに認証キーをつけ、body で送り先の token を指定し、https://fcm.googleapis.com/fcm/send に POST するだけで通知できます。 だいたいこんな感じの POST を送れば良いでしょう。 curl -X POST -H "Authorization: key=${ここにFIREBASE_API_KEYがはいります}" -H "Content-Type: application/json" -d '{ "notification": { "title": "ONIAI", "body": "あなたのプロフィールがイイねされました", "icon": "firebase-logo.png", "click_action": "https://webpush2me.firebaseapp.com" }, "to": "${ここにトークンが入ります}" }' https://fcm.googleapis.com/fcm/send あとはこの curl を連打しまくれば、通知がたくさん来ます。これであなたもマッチングアプリ強者です。やったね。会議中のミラーリング画面にひょこっと通知させたり、スマホに送ってバイブ鳴らしましょう。 モブプロ中に通知が来るとだいたいこんな感じになります。 きっと周りのみんなは「えっ、あの人、モテモテなの!すごい」ってなります。 ちなみにモテてるように見える人は、本当にモテるようになるらしいです。 マッチングアプリっぽい UI にする さあここまででpush通知機能を作ることができました。しかし、push 通知が来た時に、「どんな子から来たの。見せてよ」って言われたらどうなるでしょうか。実際にリンクから飛ぶ��index.htmlそのもののページに行ってしまいます。そこでこの章では UI を作っていきます。 この章で話したいことは、既存のプロジェクトでどのようにして web push 通知機能をいれるかです。 真面目な話、既存プロジェクトにプッシュ通知を導入するのは厄介な点があります。それは, manifest.json や firebase-message-sw.js やそれらが参照しているファイルは、ビルド後、デプロイ後の置き場所も決まっています。きちんとしたパスに置かないと、正しく動作しません。とくに JS をビルドするような開発方法をとっており、ビルド後スクリプトを別フォルダーに保存している場合にこの問題は起きます。 そこでここでは、ReactJS を使って UI を作り、そこに push を送る方法を解説します。とはいえ、難しいことは何も要求されません。ただ、ビルド時に必要なファイルをビルド先フォルダーへコピーしてあげるだけです。 いま、このような構造のディレクトリがあるとします。 $ tree -I node_modules -L 3 . ├── README.md ├── dist │ ├── 7506011b33e7e3e37f329cc8c87ba57e.jpg │ ├── build.js │ ├── firebase-messaging-sw.js │ ├── index.html │ └── manifest.json ├── firebase.json ├── package.json ├── script │ └── predeploy.sh ├── src │ ├── assets │ │ └── yk1.jpg │ ├── component │ │ └── Card.tsx │ ├── firebase-messaging-sw.js │ ├── index.d.ts │ ├── index.html │ ├── infra │ │ ├── data.ts │ │ └── firebase-messaging.ts │ ├── main.tsx │ ├── manifest.json │ ├── page │ │ └── Root.tsx │ └── vendor │ └── css ├── webpack.config.js └── yarn.lock src 配下は普通の React プロジェクトです。カードコンポーネントがあり、それが一人のプロフィールになっており、それを page/Root.tsx で並べています。また、firebase-messaging の設定は infra フォルダーに配置し、Root.tsx のマウント時で呼び出すようにしています。このプロジェクトは webpack で build すると、index.html は build.js を読み込む設定を加えられ、ビルド前のファイルは dist ディレクトリに build.js という名前で、共に吐き出されます。そしてこの dist ディレクトリをデプロイします。 その時に、index.html と build.js 以外に、push 通知に必要な manifest.json と firebase-messaging-sw.js もデプロイしないといけません。そのため、prebuild.sh という名前の build script を作成しました。 cp -r ./src/firebase-messaging-sw.js dist cp -r ./src/manifest.json dist もし、icon や badge の画像がある場合はそれも一緒にコピーしてあげましょう。 これを build 前に実行することで、FCM が必要とするファイルを dist フォルダーにコピーしましょう。 build コマンド は npm scripts で定義しています。 "build:prd": "BUILD_MODE='production' REACT_APP_ENV=production webpack", buildコマンドの前に prebuild script を実行することでFCM をデプロイ先でも利用できるようになります。 "deploy:prd": "sh ./script/predeploy.sh & yarn run build:prd & firebase deploy" これで build 処理があるようなプロジェクトでも push を受け取ることができるようになりました。 おまけ 登場人物の整理 言葉 説明 Firebase Google が提供する mobile Backend as a Service(mBaaS)。認証やストレージなどを提供しており、その機能の一つとしてメッセージ通知サービス(FCM)がある。 FCM Firebase Cloud Messaging。プッシュ通知を配信できる、Google 傘下のサービス。Android 端末だけなく、APNs 経由で iOS にも通知できる。iOS/Android 端末だけでなく Web にも通知を送れる(VAPID に対応したため)。 GCM FCM と同じくプッシュ通知を配信できるサービス。 FCM の台頭により廃止された。 APNs Apple が提供する プッシュ通知サービス。iOS に対して Push を行うことができる。 push server 各ブラウザベンダが保有している push 配信を行うためのサーバーやサービスを指す。例えば Mozilla はMozilla’s Push Serviceを持っていたり、Edge はWNS持っている。 VAPID Voluntary Application Server Identification for Web Push のこと。PUSH の送信を行うための規格。アプリケーションサーバーが作った JWT を、Push サーバーが検証し、検証に成功したら Push を送る仕組み。 service worker ブラウザが Web ページとは別にバックグラウンドで実行するスクリプト。push 通知文脈においては、メッセージの受信をユーザーに通知するために利用する。 web-push-protocol web push を行うライブラリが従っている規格。push API が実装されているブラウザはこの規格に従うように作られている。 最後に一言 いいねの数だけで人の価値は決まりません。どれだけ 1 人の大切な人を想えるかが重要なのだと思います。
0 notes
Text
How To Set Up Firebase in Ionic 4 and Angular
Google Firebase is the love of my life. It’s noSQL and easily accessible online, thanks to Google’s sweet UX team. Firebase gives you functionality like analytics, auth, databases, messaging and crash reporting so you can move quickly and focus on your users.
Interested yet? Let’s get started with Firebase and Ionic 4 by showing you how to set things up.
The setup illustrated in this post is based on an Ionic/Angular project, so this same setup will work just as well in a regular Angular project without Ionic.
🐊 Alligator.io recommends �
Ionic 4 Crash Course with Heartstone API & Angular
ⓘ About this affiliate link
Starting a New Project
Start a new Ionic 4 project that uses Angular by running the ionic start in your command line:
$ ionic start alligator_firebase --type=angular
While your new Ionic 4 project is building, let’s head over to the Firebase Console. If you are not logged into a Google account, do so now!
This is the easy part. Click the white and blue “Add Project” button and type in a name for your awesome new project under “Project Name”. I’m going to go with “Alligator”.
Click “Create Project”. Once it loads, proceed to your new project.
Getting the Config Rules
You should now be on a blue page with your project title written on the top left corner.
Click the HTML div tag icon underneath your project title. You should now see a pop-up that contains a code snippet that looks very similar to the one below.
<script src="https://www.gstatic.com/firebasejs/5.9.4/firebase.js"></script> <script> // Initialize Firebase var config = { apiKey: "djlsjdflkasjlfk__339201", authDomain: "alligator-9930.firebaseapp.com", databaseURL: "https://alligator-9930.firebaseio.com", projectId: "alligator-9930", storageBucket: "alligator-9930.appspot.com", messagingSenderId: "20948309483" }; firebase.initializeApp(config); </script>
The config credentials I am showing you above are not real API keys and URLs. Be wary when publishing Firebase configs in a repository or website. Anyone with those credentials, as we will soon see, may read and write to your database.
Copy the portion on your Firebase project that corresponds to the highlighted code above.
Install AngularFirebase Dependencies
Before you add any Firebase to your new Ionic 4 project, make sure that you have installed AngularFire2. To do so, run the following command in your CLI:
$ npm install @angular/fire
Transferring Config Rules to Ionic
Now that you have your config rules, you must paste them into a few files in your Ionic 4 app. cd into the Ionic 4 app we started, and head on over to the file environment.prod.ts (the production environment file), located in the environments folder.
Add in the config credentials that you copied earlier:
environment.prod.ts
export const environment = { production: true, firebase: { apiKey: "your_apiKey", authDomain: "your_authDomain", databaseURL: "your_databaseURL", projectId: "your_projectID", storageBucket: "your_storageBucket", messagingSenderId: "your_messagingSenderId" } };
Next, head over to the environment.ts, located in the same folder:
environment.ts
export const environment = { production: false, firebase: { apiKey: "your_apiKey", authDomain: "your_authDomain", databaseURL: "your_databaseURL", projectId: "your_projectId", storageBucket: "your_storageBucket", messagingSenderId: "your_messagingSenderId" } };
Finally, locate the root module file (app.module.ts). Import your newly installed @angular/fire modules and your environment.ts file like the highlighted code snippet below.
app.module.ts
// ... // firebase imports, omit what you don't need for your app import { AngularFireModule } from '@angular/fire'; import { AngularFireAuthModule } from '@angular/fire/auth'; import { AngularFireDatabaseModule } from '@angular/fire/database'; import { AngularFireStorageModule } from '@angular/fire/storage'; // environment import { environment } from '../environments/environment'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [ BrowserModule, IonicModule.forRoot(), AppRoutingModule, AngularFireModule.initializeApp(environment.firebase), AngularFireAuthModule, AngularFireDatabaseModule, AngularFireStorageModule ],</span> // ...
That's all there is to it! Go out there and make your AngularFire Ionic app a success!
via Alligator.io http://bit.ly/2Gl8JsT
0 notes
Text
Discovering Firebase
Firebase is a mobile and web application platform that includes a real-time database. Let's start using it with JS in a really simple manner.
First, we include Firebase in our project by using https://www.gstatic.com/firebasejs/3.7.5/firebase.js
Now, let's initialize the app!
var firebaseConfig = { apiKey: "apiKey", authDomain: "yourProtectedID.firebaseapp.com", databaseURL: "https://databasename.firebaseio.com", storageBucket: "yourProtectedID.appspot.com", messagingSenderId: "messagingSenderId" }; var firebaseApp = firebase.initializeApp(firebaseConfig); var firebaseDatabase = firebaseApp.database();
Then, because we'd like to retrieve some data, we create a reference to the query location, in the example, "posts".
var ref = firebaseDatabase.ref("posts");
We can now retrieve data from "posts" like so:
ref.on('value', function(data) { doSomethingWithData(data.val()); });
The on method listens for changes permanently. If we need to listen only once, we can use the method once like this:
ref.once('value').then(function(data) { doSomethingWithData(item); });
And now, let's delete some data!
firebaseDatabase.ref("posts").child(item.key).remove();
0 notes