Smart Mirror Web Uygulaması

Merhaba değerli dostlar,

Bu yazıda geliştireceğimiz basit bir web sayfası ile Firebase veritabanına etkinliklerimizi kayıt edip var olan etkinlikleri listelemeyi sağlayacağız. Firebase, verileri saklayacağımız ortak platformumuz olup diğer tüm uygulamalar kayıtlı olan etkinlikleri buradan alıp kullanıcıya sunacaktır. Akıllı ayna projemizde veri bütünlüğünü ve paylaşımını sağlamak için Firebase bizlere oldukça yardımcı olacaktır. Tabi isterseniz kendi backend sisteminizi de oluşturup  kullanabilirsiniz. İşlerin pratik ve çabuk olması bakımından Firebase şimdilik en ideal yol olarak görünmektedir. Web uygulamasına geçmeden önce Firebase ortamına geçelim ve yeni bir proje oluşturalım.

Firebase Ortamında Yeni Proje Oluşturmak

Firebase ortamında oluşturacağımız bu projeyi daha sonra geliştireceğimiz Android uygulamalarının tamamında kullanacağız. Tabi burada bir web sayfasından alınan verilerin Firebase Real Time Database ortamına kayıt işlemi yapılacağı için yapılması gereken bazı düzenlemeler var.

Öncelikle Firebase Console sayfasına gidelim. Firebase bir Google hizmeti olduğu için Gmail hesabınızın olması gerekiyor. Sisteme giriş yaptıktan sonra aşağıdaki pencere bizleri karşılar.

Yukarıda bulunan açılan pencerede, Proje ekle seçeneğine tıklayınız.

Proje adını giriniz ve ülke/bölge seçeneğini Türkiye olarak değiştirip Proje Oluştur düğmesine tıklayınız.

Yukarıdaki gibi proje oluşturuluyor mesajı gösterildikten kısa bir süre sonra projemiz aşağıdaki gibi oluşturulur.

Devam seçeneğine tıklayarak proje alanına geçelim.

Amacımız Firebase ile bir web sayfası arasındaki iletişimi sağlamaktır. Bunun için yukarıda verilen üç seçenekten “Firebase’i web uygulamanıza ekleyin” seçeneğine tıklayalım. Açılan sayfada aşağıdaki kodlar bizlere gösterilir.

Kopyala seçeneğine tıklayıp ilgili satırları kopyalabilirsiniz. Burada verilen satırlar web uygulaması ve Firebase arasındaki iletişimi sağlayacaktır. Firebase’de yapacağımız işlemleri burada bırakıp web uygulamasına geçebiliriz.

Web Sayfasını Oluşturmak

Firebase ortamında bir proje oluşturduk. Şimdi bu proje yardımıyla Firebase ortamına veri kaydını yapmayı sağlayan web sayfasını tasarlayabiliriz. Oluşturacağımız web sayfasının üç temel amacı bulunmaktadır:

  • Firebase ortamına veri kaydını sağlamak,
  • Var olan kayıtların listesini kullanıcıya göstermek,
  • Ve son olarak mevcut bir kaydın silinmesini sağlamaktır.

Web uygulamasını tasarlarken uygulama kodlarını tek bir html sayfasında değil farklı sayfalarda yazacağız. Uygulamanın temel kodlarını aşağıdaki üç farklı dosyada ele alacağız:

  • index.html: Sitenin temel html kodları buraya yazılacaktır.
  • style.css: web sayfasının tasarım ve görsellik ile ilgili kodları buraya eklenecektir.
  • index.js: Firebase ile ilgili işlemleri yazacağımız kodlar buraya eklenecektir.

Öncelikle web sayfamızın index.html isimli dosyasının kodlarını paylaşmak istiyorum.

İndex.html

Web sayfamız tek bir html dosyasından meydana gelecektir. Kullanıcı tüm işlemlerini buradan yapacaktır. Faaliyet kaydı, var olan kayıtların listelenmesi veya mevcut olan bir kaydın silinebilmesi için html etiketlerine ihtiyacımız bulunmaktadır. Uygulama için gereken tüm etiketleri burada tanımladık. Bu sayfamız için kullanacağımız kodlar açıklamalarıyla birlikte aşağıdaki gibidir:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Smart Mirror</title>
<!--style.css dosyamızı ekledik. Stil ile ilgili işlemleri html kodlarımızdan ayrı olarak ele aldık. -->
<link rel="stylesheet" type="text/css" href="style.css">


<!—Firebase ile iletişimi sağlayacak kodları index.js içinde yazdık. -->
<script src="index.js"></script>

</head>
<body >
<div class="mainDiv" align="center">
  <h2 align="center" id="heading">Registration Form</h2>
  <!--Faaliyet kayıt işlemini yapmayı sağlayan tablomuz. -->
  <table border="0" align="center" width="700px">
      <tr>
          <!--Faaliyet için tarih bilgisi -->
          <td><label for="fdate">Date</label></td>
          <td><input type="date" name="bday" ></td>
      </tr>
      <tr>
          <!--Faaliyet için zaman bilgisi -->
          <td><label for="lname">Time</label></td>
          <td><input type="time" name="btime" ></td>
      </tr>

      <tr>
          <!--Faaliyet için başlık bilgisi -->
          <td><label for="ltitle">Title</label></td>
          <td><input type="text" name ="title" placeholder="Title.."></td>
      </tr>

      <tr>
          <!--Faaliyet için açıklama bilgisi -->
          <td><label for="ldesc">Description</label></td>
          <td><textarea id="mainText" name="note" 
              placeholder="Description..."></textarea>
          </td>
      </tr>

      <tr>
          <td colspan="2">
            <button id="submitBtn" onClick="saveData()">Save Your Activity 
            </button>
          </td>
      </tr>

  </table>

  <!--Firebase ortamında kayıtlı olan etknlikleri listeleyeceğimiz tablo -->
  <table border="1" align="center" width="700px" id="notelist">
    <caption style="margin-bottom: 20px">Registered Activities</caption>
    <tr>
      <!--Kayıtlı olan verileri tarih, saat, başlık, açıklama ve silme
      sütunlarında göstereceğiz. -->
      <th>Date</th>
      <th>Time</th>
      <th>Title</th>
      <th>Description</th>
      <th>Completed</th>
    </tr>

    <!--Kayıtlı olan faaliyetlerin tümü tbody etiketi altında 
    listelenecektir. -->
    <tbody id="table_body"></tbody>
  </table>
<p>Created by <a href="https://memetalisicak.com/" target="new" style="color: blue">Mehmet Ali SICAK</a></p>
</div>
<a href="https://memetalisicak.com/" target="new">
<div class="footer">
<b>Visit My Blog</b>
</div>
</a>

</body>
</html>

 

Style.css

Web sayfaları tasarlarken HTML ve CSS kodlarının birbirinden ayrı olarak ele alınması oldukça önemlidir. Biz de burada bu işlemi yaptık. Bu sayfa için ihtiyacımız olan stil yani CSS kodları aşağıdaki gibidir:

@charset "utf-8";
/* CSS Document */

/*Body etiketi için font türü ve arkaplan rengini belirledik.*/
body{
   font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
   background-color: #720e62;
}

/*mainDiv için genişlik değerini %55 olarak ayarladık ve div etiketini margin ile sayfaya ortaladık.*/
.mainDiv{
   width: 55%;
   margin: 0 auto;
}

/*Kayıtlı olan not yani faaliyetleri listeleyeceğimiz tablo için stil özelliklerini tanımladık.*/
#notelist {
   border-collapse: collapse;
   width: 100%;
}

#notelist td, #notelist th {
   border: 1px solid #ddd;
   padding: 8px;
}

#notelist tr:nth-child(even){
   background-color: #f2f2f2;
}

#notelist tr:hover {
   background-color: #ddd;
}

#notelist th {
   padding-top: 12px;
   padding-bottom: 12px;
   text-align: left;
   background-color: #720e62;
   color: white;
}

/*Herbir label için yazı boyutunu 18px olarak ayarladık.*/
label{
   font-size: 18px;
}

/*input[] ifadesi ile veri girişi yapacağımız alanların stil özelliklerini belirledik.*/
input[type=text],input[type=date], input[type=time],textarea {
   width: 100%;
   padding: 12px 20px;
   margin: 8px 0;
   display: inline-block;
   border: 1px solid #ccc;
   border-radius: 4px;
   box-sizing: border-box;
}

/*Kayıt işlemini yapan buton*/
#submitBtn {
   width: 30%;
   margin: 0 auto;
   float: right;
   background-color: #720e62;
   color: white;
   padding: 14px 20px;
   border: none;
   border-radius: 4px;
   cursor: pointer;
}

/*Kayıt işlemini yapan butonun üstüne farenin imleci geldiğinde arkaplan rengi değişir.*/
#submitBtn:hover {
   background-color: #45a049;
}

/*Tüm div etiketleri için ortak bir stil tanımladık.*/
div {
   border-radius: 5px;
   background-color: #f2f2f2;
   padding: 20px;
}

/*footer isteğe bağlı. Buraya kendimle ilgili bilgilere erişim sağlayan bir link ekledim.*/
.footer {
   position: fixed;
   right: 0;
   bottom: 0;
   width: 10%;
   height: 20px;
   margin-bottom: 5px;
   background-color: darkred;
   color: white;
   text-align: center;
}

a{
   text-decoration: none;
   color: white;
}

.footer:hover{
   background-color: #45a049;
}

HTML ve CSS kodlarımızı yazdıktan sonra web sayfamızın görünümü aşağıdaki gibi olur.

Kayıt yapılan alan net olarak aşağıdaki gibidir.

HTML ve CSS kodlarından sonra asıl işlemi yapan Java Script kodlarına geçebiliriz.

İndex.js

Bu dosyada yazacağımız kodlar ile Firebase ortamına bağlanıp veri kayıt işlemini sağlayacağız. Ayrıca kayıtlı olan verilerin listelenmesi veya mevcut olan bir kaydın silinmesini yine buradaki kodlar ile gerçekleştireceğiz. Öncelikle Firebase ile iletişim sağlayan kodlarımızı yazalım. Firebase için oluşturduğumuz projeye dönüp aşağıdaki pencereyi açalım.

Yukarıda işaretli olan yerleri ilgili sayfalara ekleyiniz. Bunu yapma sebebimiz Java Script ve HTML kodlarını birbirinden ayırmamızdır. Eğer tek bir sayfada işlemleri yapacaksanız bu durumda böyle bir işlemi yapmanıza gerek yok.

İndex.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Smart Mirror</title>

<link rel="stylesheet" type="text/css" href="style.css">

<!—Bu satır firebase ile ilgili işlemlerde öncelikle eklenmelidir. -->
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase.js"></script>

<!—Firebase veritabanı işlemleri için aşağıdaki satırı ayrıca eklemek gerekiyor. -->
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-database.js"></script>

<script src="index.js"></script>
</head>

HTML kodumuza veritabanı işlemlerini yapmayı sağlayan bir satır daha ekledik. Bunu eklemediğiniz zaman Firebase ortamındaki veritabanına veri kayıt işlemini yapamayız. Ayrıca eğer ihtiyacınız varsa aşağıdaki satırları da ekleyebilirsiniz.

Authentication (Doğrulama)

<script src="https://www.gstatic.com/firebasejs/5.1.0/firebase-auth.js"></script>

Cloud Firestore


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

Cloud Messaging


<script src="https://www.gstatic.com/firebasejs/5.1.0/firebase-messaging.js"></script>

Cloud Function


<script src="https://www.gstatic.com/firebasejs/5.1.0/firebase-functions.js"></script>

Şimdilik sadece database hizmetinden faydalanmak bizim için yeterli olacaktır.

İndex.js dosyamız başlangıçta aşağıdaki kodlara sahip olacaktır.


// Firebase başlatılır.
var config = {
   apiKey: "AIzaSyC30urzySPG0rSwGrPgCPsG1S2UYG7CpWE",
   authDomain: "smart-mirror-4c629.firebaseapp.com",
   databaseURL: "https://smart-mirror-4c629.firebaseio.com",
   projectId: "smart-mirror-4c629",
   storageBucket: "smart-mirror-4c629.appspot.com",
   messagingSenderId: "705683740355"
};

firebase.initializeApp(config);

Yukarıda eklediğimiz satırlar, Firebase ile olan iletişimi başlatmayı sağlar. Şimdi index.html sayfasından gelen verileri alıp Firebase ortamına kayıt eden, kayıtlı olan tüm verileri listeleyen ve mevcut olan bir kaydı silmeyi sağlayan index.js dosyamızın tüm kodlarını açıklamalarıyla birlikte verelim.


//Firebase başlatılır.
var config = {
   apiKey: "AIzaSyC30urzySPG0rSwGrPgCPsG1S2UYG7CpWE",
   authDomain: "smart-mirror-4c629.firebaseapp.com",
   databaseURL: "https://smart-mirror-4c629.firebaseio.com",
   projectId: "smart-mirror-4c629",
   storageBucket: "smart-mirror-4c629.appspot.com",
   messagingSenderId: "705683740355"
};

firebase.initializeApp(config);

/*HTML sayfasında bulunan; tarih, saat, başlık ve açıklama verilerine erişmek için ilgili kontrollere erişim sağlanır.*/
var bday = document.getElementsByName("bday");
var btime = document.getElementsByName("btime");
var title = document.getElementsByName("title");
var mainText = document.getElementsByName("note");


/*Kayıt işlemini yapan butona erişim sağlanır.*/
var submitBtn = document.getElementById("submitBtn");

function saveData(){
   /*Tarih bilgisi alınır değişkene atanır.*/
   var getDate=bday[0].valueAsDate;

   /*Alınan tarih bilgisi dd.mm.yyyy formatı olarak yeniden düzenlenir ve 
   yeni bir değişkene atanır.*/
   var date = getDate.getDate()+"."+
             (getDate.getMonth()+1)+"."+getDate.getFullYear();

   /*Zaman bilgisi alınır ve değişkene atanır*/
   var getTime = btime[0].value;

   /*Firebase ortamında veriler key-value olarak kayıt edilir. Value 
   bilgisini kullanıcının girdiği tarih, saat, başlık ve açıklama 
   verilerinden elde edeceğiz, key bilgisini ise anlık zaman 
   bilgisinden elde edeceğiz.*/
   var d = new Date();
   var n = d.getTime();

   /*Firebase ortamında veriyi kayıt edeceğimiz bir JSON dizisi
   tanımladık. Burada mynotes, dizinin ismi olacaktır*/
   var firebaseRef = firebase.database().ref("mynotes");

   /*Tarih, saat, başlık ve açıklama verileri arasına tire işareti 
   ekledik ve yeni bir veri elde ettik. Burada elde edilen veri 
   Firebase ortamına kayıt edeceğimiz veridir.*/
   var msg = date+"-"+getTime+"-"+title[0].value+"-"+mainText[0].value;

   /*Aşağıdaki satır ile n key (o anki zaman) bilgisine karşılık
   msg verisini kayıt ettik. Böylece kayıt işlemi tamamlanmış olur.*/
   firebaseRef.child(n).set(msg);

   /*Yeni kayıt için etiketler resetlenir.*/
   bday[0].value='';
   btime[0].value='';
   mainText[0].value='';
   title[0].value='';
}

/*table_body id bilgisine sahip olan etikette kayıtlı olan tüm veriler listelenir. Listeleme yapmadan önce aşağıdaki metot ile öncelikle bu etikette bulunan tüm verilerin silinmesi sağlanır */
function removeAllChildsss(){

   /*table_body id bilgisine sahip etikete erişim sağlanır*/
   var list2 = document.getElementById("table_body");

   /*while döngüsü ile bu etikette herhangi bir verinin olup
   olmadığı kontrol edilir. Eğer varsa removeChild ile verinin 
   silinmesi sağlanır.*/
   while (list2.hasChildNodes()) {
      list2.removeChild(list2.firstChild);
   }

}

/*Bu metot ile varsa kayıtlı verilerin listelenmesi sağlanır*/
getList();

/*Firebase ortamında kayıtlı olan tüm verilerin listelenmesini sağlayan metot.*/
function getList(){

   /*Firebase veritabanında verilerimizi mynotes JSON tagı altında kayıt 
   edeceğimiz için verilere erişmek için yine mynotes tagını kullandık.
   Bu şekilde varsa kayıtlı olan tüm verilerin list değişkenine atanması 
   sağlanmış olur.*/
   var list = firebase.database().ref("mynotes");

   /*on metodu ile firebase ortamındaki verilen okunması hatta varsa 
   veri değişikliklerinin algılanması sağlanır.*/
   list.on("child_added",snap => {

      /*snap.val() ile elde edilen veriyi split ile parçaladık. 
      Kayıt işleminde tarih, saat, başlık ve açıklama verileri 
      arasına tire eklediğimiz için veriyi parçalarken tire 
      karakterini kullandık. Böylece elimizde bir dizi oluşur.*/
      var res = snap.val().split("-");
      var i;
      var r = document.createElement("TR");

      /*Kayıtlı olan veriler listelenir.*/
      for (i = 0; i < res.length; i++) {
         var t = document.createElement("TD");
         var text = document.createTextNode(res[i]);
         r.appendChild(t);
         t.appendChild(text);
      }

      /*Veriler listelendikten hemen sonra bir tane buton ekledik. 
      Bu buton ilgili kaydın silinmesini sağlayacaktır.*/
      var t2 = document.createElement("TD");
      var b = document.createElement("BUTTON");
      var bText = document.createTextNode("Yes");
      r.appendChild(t2);
      t2.appendChild(b);
      b.appendChild(bText);

      /*Butona tıklama olayı tanımladık. Tıklandıktan sonra snap.key
      ile key bilgisi verilen veri Firebase ortamından silinir.*/
      var att = document.createAttribute("onclick");
      att.value = "removeAct("+snap.key+")";
      b.setAttributeNode(att);

      document.getElementById("table_body").appendChild(r);
    });
}

/*key bilgisi verilen veriyi silen metodumuz*/
function removeAct(x) {
   var firebaseRef = firebase.database().ref("mynotes");
   firebaseRef.child(x).remove();
   removeAllChildsss();
   getList();
}

Şimdi yazdığımız kodlarımızı test edebiliriz. Test işlemine geçmeden önce Firebase ortamına veri kaydını yapabilmek için projemizde aşağıdaki sayfaya geri dönelim.

“Database” seçeneğine tıkladıktan hemen sonra yeni bir sayfa bizleri karşılar. Açılan sayfada aşağıdaki alana geliniz.

Burada Realtime Database özelliğini kullandığımıza dikkat etmenizi istiyorum. “Veritabanı oluşturun” seçeneğine tıklayınız. Aşağıda açılan pencerede veritabanı güvenlik seviyesini test olarak ayarlayınız. Bu aslında güvenli bir yöntem değildir. Ancak konumuzun dışında olduğu ve yazımızı daha fazla uzatmamak adına bu şekilde devam edeceğiz. Bu seçenekle beraber veritabanına herkesin erişim sağlamasına izin verilmiş olur.

“Etkinleştir” seçeneğine tıklayarak devam ettikten sonra artık veritabanı işlemlerini rahatlıkla yapabiliriz.

Firebase Ortamına Veri Kaydını Yapmak

Tüm bu işlemlerden sonra web sayfamızı açalım ve ilgili alanlara aşağıdaki değerleri girelim.

Save butonuna tıkladıktan sonra eklediğimiz verinin listelendiğini görebilirsiniz.

Firebase ortamına baktığımız zaman verinin eklendiğini buradan da görebiliriz.

Bir sonraki yazıda Raspberry Pi 3 yani Android Things ortamında çalışacak uygulamanın kodları hakkında sizlere bilgi vereceğim. Şimdilik bu kadar….