firebase使用_如何使用HTML,CSS,JavaScript和Firebase构建事件预订应用程序

firebase使用

In this tutorial, we are going to build an Event Booking App with HTML, CSS, JavaScript, and Firebase.

在本教程中,我们将使用HTML,CSS,JavaScript和Firebase构建一个Event Booking App。

规划我们的应用 (Plan our app)

We are not going to build a complete event booking app with all the functionality. We don't need to cover everything in just one tutorial. Since I just want to keep things simple and easy to digest, we'll go over the authentication part in a separate article.

我们不会构建具有所有功能的完整的事件预订应用程序。 我们不需要在一个教程中涵盖所有内容。 由于我只是想使事情简单易懂,因此我们将在另一篇文章中介绍身份验证部分。

So, our Event Booking App will have the following functionalities:

因此,我们的活动预订应用程序将具有以下功能:

  • The user can create an event and store it to Firestore.

    用户可以创建事件并将其存储到Firestore。
  • The user can fetch all events in real-time.

    用户可以实时获取所有事件。
  • The user can book an event.

    用户可以预订事件。
  • The user can't book an event more than once.

    用户最多只能预订一个活动。

Now that we know what our app will look like, let's start building it in the next section.

现在我们知道了我们的应用程序的外观,让我们在下一部分开始构建它。

标记 (Markup)

Our HTML file will be relatively simple. We will hold our navigation bar and the latest event in the header tag.

我们HTML文件将相对简单。 我们将在header标签中保留导航栏和最新事件。

  • In index.html

    index.html

<body>
    <header id="home">
      <nav class="navbar">
        <h1>Eventic</h1>
        <ul>
            <li><a href="#home">Home</a></li>
            <li><a href="#events">Events</a></li>
            <li><a href="#add-event">New Event</a></li>
        </ul>
      </nav>
      <div class="welcome-event"></div>
    </header>
    <main>
        <section id="events">
            <h1 class="section-title">Events</h1>
            <div class="events-container"></div>
        </section>
        <section id="add-event">
            <h1 class="section-title">New Event</h1>
            <form class="form">
                <input type="text" id="name" placeholder="Name">
                <input type="number" id="attendee" placeholder="Attendees">
                <textarea id="description" cols="30" rows="10" placeholder="Description..."></textarea>
                <select id="status">
                    <option value="0">Free</option>
                    <option value="1">Paid</option>
                </select>
                <button class="btn btn-primary">Save</button>
            </form>
        </section>
    </main>

Next, the main tag will wrap the list of events and the form which enables us to create a new event.

接下来, main标签将包装事件列表和表单,使我们能够创建新事件。

The events will be displayed later with the help of JavaScript.

稍后将在JavaScript的帮助下显示事件。

  • In index.html

    index.html

<script src="https://www.gstatic.com/firebasejs/7.9.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.9.1/firebase-firestore.js"></script>

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    authDomain: "xxxxxxxxxxxxxxxxxxxxxxxx",
    databaseURL: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    projectId: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    storageBucket: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    messagingSenderId: "xxxxxxxxxxxxxxxxxxxxxxxxx",
    appId: "xxxxxxxxxxxxxxxxxxxxxxxxx"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  const db = firebase.firestore()
</script>

<script src="db.js"></script>
<script src="app.js"></script>

</body>
</html>

Next, we need to connect our app to Firebase to be able to store our data.

接下来,我们需要将我们的应用程序连接到Firebase才能存储我们的数据。

To have these credentials, you will need to create a new app in the Firebase Console. And once the project created, click on the code icon </> that sits next to the iOS and Android icons to register your app.

要获得这些凭据,您将需要在Firebase控制台中创建一个新应用。 创建完项目后,单击iOS和Android图标旁边的代码图标</>注册您的应用。

Now, to generate the credentials, you have to register the name of your app.And finally, put the credentials in the HTML file as I do here.

现在,要生成凭据,您必须注册您的应用程序名称。最后,像我在此处一样将凭据放入HTML文件中。

Next, duplicate the first script tag and change firebase-app.js to firebase-firestore.js because we will use Firestore in this project.

接下来,复制第一个script标签,并将firebase-app.js更改为firebase-firestore.js因为我们将在此项目中使用Firestore。

Then, initialize firebase with the configuration and declare a db variable that will be used later to interact with Firebase.

然后,使用配置初始化firebase并声明一个db变量,该变量将在以后与Firebase进行交互。

Now, we have our markup and have successfully linked our project to Firebase. So let's start styling it in the next section.

现在,我们有了标记,并已成功将我们的项目链接到Firebase。 因此,让我们在下一部分中开始设计样式。

造型 (Styling)

The CSS file is a bit long, so I won't cover everything in this post. I will just highlight the most important parts. However, no worries, you will find the source code at the end of the article.

CSS文件有点长,所以我不会在本文中介绍所有内容。 我将只重点介绍最重要的部分。 但是,不用担心,您将在本文结尾处找到源代码。

As usual, we start by importing our font and doing some resets to prevent the default behavior.

与往常一样,我们首先导入字体并进行一些重置以防止出现默认行为。

  • In style.css

    style.css

@import url('https://fonts.googleapis.com/css?family=Nunito:400,700&display=swap');

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
    --primary-color:#e74c3c;
    --secondary-color:#222;
    --tertiary-color:#333;
    --light-color: #fff;
    scroll-behavior: smooth; 
}

body {
    background-color: #1f1f1f;
    font-family: 'Nunito', sans-serif;
    font-size: 1rem;
    color: var(--light-color);
    line-height: 1.6;
}

Next, we use CSS Variables to store our colors and set the scroll-behavior to smooth so we have a nice scrolling effect when the user clicks in the navbar links.

接下来,我们使用CSS变量存储颜色并将scroll-behavior设置为smooth以便在用户单击导航栏链接时具有很好的滚动效果。

However, be careful with the scroll-behavior, as it's not supported by all browsers. You can check on browser compatibility here.

但是,请注意scroll-behavior ,因为并非所有浏览器都支持 scroll-behavior 。 您可以在此处检查浏览器的兼容性。

  • In style.css

    style.css

nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem 2.5rem;
    z-index: 100;
    width: 100%;
    transition: background 0.3s;
    position: fixed;
    top: 0;
    left: 0;
}

nav ul {
    display: flex;
    list-style: none;
}

nav li:not(:last-child), .welcome-event div span {
    margin-right: 1.5rem;
}

For the navbar, by default, the background will be transparent. For better usability, it will change when the user starts scrolling.

对于导航栏,默认情况下,背景将是透明的。 为了更好的可用性,当用户开始滚动时它将改变。

Our Event Booking App is starting to take shape. Now let's start implementing Firebase and connect our app to Firestore.

我们的活动预订应用程序已初具规模。 现在,让我们开始实施Firebase并将我们的应用程序连接到Firestore。

与Firebase互动 (Interact With Firebase)

Firebase is a platform that handles everything related to the back-end for us. The only thing we have to do is connect our app to it and start using the database or other services.

Firebase是一个平台,可以为我们处理与后端相关的所有事情。 我们唯一要做的就是将我们的应用程序连接到它,然后开始使用数据库或其他服务。

Firestore is a NoSQL database, and it's non-relational and uses documents, collections, and so on to create the database.

Firestore是NoSQL数据库,它是非关系数据库,并使用文档,集合等来创建数据库。

Now, let's connect to Firestore and create our very first database.

现在,让我们连接到Firestore并创建我们的第一个数据库。

提取事件 (Fetch events)

Earlier in this tutorial, we had declared a variable db in the HTML part. Now, let's use that variable to connect our app to Firestore.

在本教程的前面,我们在HTML部分中声明了一个变量db 。 现在,让我们使用该变量将我们的应用程序连接到Firestore。

I will put everything related to the database on the db.js file to just have a cleaner structure.

我将与数据库相关的所有内容放在db.js文件中,以使其结构更整洁。

  • In db.js

    db.js

db.collection('events').onSnapshot(snapshot => {
    // Handle the latest event
    const newestEvent = snapshot.docChanges()[0].doc.data()
    const id = snapshot.docChanges()[0].doc.id
    showLatestEvent(newestEvent, id);
    
    // delete the latest event element
    snapshot.docChanges().shift()
    
    snapshot.docChanges().forEach(event => {
        showEvents(event.doc.data(), event.doc.id)
    });
})

With the help of db, we can now access our collection events. It's just the name of our database, and if it doesn't exist Firestore will create it on the fly for us.

db的帮助下,我们现在可以访问我们的收集events 。 它只是我们数据库的名称,如果不存在,Firestore会为我们动态创建它。

The collection object has a very handy method called onSnapshot(). It helps us listen in real-time to the database. This means that whenever a change occurs on it, it will react and return the change in real-time.

集合对象有一个非常方便的方法,称为onSnapshot() 。 它可以帮助我们实时侦听数据库。 这意味着无论何时发生更改,它都会做出React并实时返回更改。

The onSnapshot() method will also help us access the document (our data). And now, we can extract the latest event to show on the header. And, before looping through the events array, delete the latest event so that it doesn't display it again.

onSnapshot()方法还将帮助我们访问文档(我们的数据)。 现在,我们可以提取最新事件以显示在标题上。 并且,在循环事件数组之前,请删除最新事件,以使其不再显示。

Now, to display the events on the UI, we have to call our necessary functions showLatestEvent() and showEvents(). Then we pass the event and the id to them as parameters.

现在,要在UI上显示事件,我们必须调用必要的函数showLatestEvent()showEvents() 。 然后,我们将事件和ID作为参数传递给他们。

We can now fetch the events from Firestore, but we still don't have any events to show. Let's store our very first event in our database.

现在,我们可以从Firestore中获取事件,但是仍然没有任何事件可以显示。 让我们将第一个事件存储在数据库中。

建立活动 (Create an event)

To get the values entered by the user, we have to first select the form tag and use it to pick the id of each input and pull the value entered.

为了获得用户输入的值,我们必须首先选择form标签,并使用它来选择每个输入的ID并提取输入的值。

  • In db.js

    db.js

const addNewEvent = () => {
  const event = {
    name: form.name.value,
    attendee: form.attendee.value,
    booked: 0,
    description: form.description.value,
    status: parseInt(form.status.value, 10)
  }
    db.collection('events').add(event)
    .then(() => {
    // Reset the form values
    form.name.value = "",
    form.attendee.value = "",
    form.description.value = "",
    form.status.value = ""

    alert('Your event has been successfully saved')
    })
    .catch(err => console.log(err))
}

The db variable (remember it's the reference to firebase.firestore()) has another method to save data to Firestore: the save() function. It's a promise, and once it's complete, we can now reset the values of the form and show a success message to the user.

db变量(请记住是对firebase.firestore()的引用)还有另一种将数据保存到Firestore的方法: save()函数。 这是一个承诺,一旦完成,我们现在就可以重置表单的值并向用户显示成功消息。

Now, let's move on and handle the case when the user wants to book an event.

现在,让我们继续处理用户想要预订事件的情况。

预订活动 (Book an event)

As I said earlier, we can't check if the user is authenticated or not, so they can potentially book an event more than once.

如前所述,我们无法检查用户是否已通过身份验证,因此他们有可能多次预订活动。

So to handle this, I will use localStorage to prevent booking duplication.

因此,为了解决这个问题,我将使用localStorage防止预订重复。

  • In db.js

    db.js

let bookedEvents = [];

const bookEvent = (booked, id) => {
  const getBookedEvents = localStorage.getItem('booked-events');

    if (getBookedEvents) {
     bookedEvents = JSON.parse(localStorage.getItem('booked-events'));
      if(bookedEvents.includes(id)) {
        alert('Seems like you have already booked this event') 
      } 
      else {
        saveBooking(booked, id)
     }
    } 
    else {
        saveBooking(booked, id)
    }
};

const saveBooking = (booked, id) => {
    bookedEvents.push(id);
    localStorage.setItem('booked-events', JSON.stringify(bookedEvents));

    const data = { booked: booked +1 }
    db.collection('events').doc(id).update(data)
    .then(() => alert('Event successfully booked'))
    .catch(err => console.log(err))
}

And as you can see here, we first check if the event id is stored or not in localStorage. If it is, the user can't book the same event again. Otherwise, they will be able to book the event.

正如您在此处看到的那样,我们首先检查事件ID是否存储在localStorage中。 如果是,则用户无法再次预订同一事件。 否则,他们将可以预订活动。

And to update the booking counter, we use again db to update the event on Firestore.

为了更新订票柜台,我们再次使用db更新Firestore上的事件。

The db.js file is now complete, So, let's move to the final part and connect our project to db.js

db.js文件现在已完成,因此,让我们移至最后一部分并将我们的项目连接到db.js

使用JavaScript显示和更新数据 (Show and Update Data with JavaScript)

As usual, we start by selecting the necessary elements.

与往常一样,我们从选择必要的元素开始。

const eventsContainer = document.querySelector('.events-container')
const nav = document.querySelector('nav')
const welcomeEvent = document.querySelector('.welcome-event')
const form = document.querySelector('.form')

const showEvents = (event, id) => {
  const {name, attendee, status, description, booked} = event

  const eventStatus = status === 0 ? 'free': 'paid'
  const output = `
        <div class="card">
          <div class="card--details">
            <div>
              <h1>${name}</h1>
              <span>${attendee - booked} attendees</span>
            </div>
            <span class="card--details-ribbon ribbon-${eventStatus}">
                ${eventStatus}
            </span>
             <p>${description}</p>
            <button onclick="bookEvent(${booked} ,'${id}')" class="btn btn-tertiary">Book</button>
          </div>
        </div>
        `
    eventsContainer.innerHTML += output;
}

Earlier in this article, we had passed as a parameter to the showEvents() function the event fetched from Firestore in the db.js file.

在本文的前面,我们已将db.js文件中从Firestore提取的事件作为参数传递给showEvents()函数。

We can now pull the values held on the event object and display it. And, when the user clicks on the button to book an event, we will call the bookEvent() function to handle it.

现在,我们可以拉出事件对象上保存的值并显示它。 而且,当用户单击按钮预订事件时,我们将调用bookEvent()函数来处理该事件。

const showLatestEvent = (latestEvent, id) => {
  
  const {name, attendee, status, description, booked} = latestEvent 
  // Get the first event
    welcomeEvent.innerHTML = `
    <h1>${name}</h1>
    <p>${description.length >= 100 ? `${description.substring(0, 100)}...` : description}</p>
    <div>
      <span>Attendees: ${attendee - booked}</span>
      <span>Status: ${status === 0 ? 'free': 'paid'}</span>
     </div>
     <button onclick="bookEvent(${booked} ,'${id}')" class="btn btn-tertiary">Book</button>
    `
}

form.addEventListener('submit', e => {
  e.preventDefault()
  addNewEvent()
})

window.onscroll = () =>  {
  if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
    nav.style.background = 'var(--tertiary-color)';
    nav.style.boxShadow = '0 10px 42px rgba(25,17,34,.1)';
  } else {
    nav.style.background = 'none';
    nav.style.boxShadow = 'none';
  }
}

As you can see, the showLatestEvent() method is quite similar to showEvents(), unlike the element used to display the event.

如您所见,与用于显示事件的元素不同, showLatestEvent()方法与showEvents()非常相似。

And, when the description is a bit long, we use substring() to truncate the value.

并且,当描述有点长时,我们使用substring()截断该值。

Next, we listen to the form element to handle the submit event and store it to Firestore with addNewEvent().

接下来,我们监听form元素以处理addNewEvent()事件,并使用addNewEvent()将其存储到Firestore中。

And to make everything looking nice, when the user scrolls we add a background color and a box-shadow to the navigation bar.

为了使所有内容看起来都不错,当用户滚动时,我们在导航栏中添加了背景色和阴影。

With that change, we have now our Event booking App using JavaScript and Firebase.

有了这一更改,我们现在有了使用JavaScript和Firebase的活动预订应用程序。

Thanks for reading this article.

感谢您阅读本文。

You can check it live here or find the Source Code here.

您可以在此处进行实时检查,也可以在此处找到源代码

Read more articles on my blog - Subscribe to my newsletter - Follow me on twitter

在我的博客上阅读更多文章 - 订阅我的新闻通讯 - 在Twitter上关注我

翻译自: https://www.freecodecamp.org/news/how-to-build-an-event-booking-app-using-html-css-javascript-and-firebase/

firebase使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值