Geliştirici masasında açık kod editörü, kahve fincanı, kulaklık ve iş monitörü.

Fotoğraf: Christopher Gower / Unsplash

Bu bağlantı üzerinden ulaşabileceğiniz ilk yazımdan sonra, birkaç haftadır Quasar ve Vue.js ile çalışıyorum. Lebib Yalkın Yayınları’nda, eskiden Flutter ile yazılan mobil uygulamayı Quasar ve Vue.js teknolojileri kullanarak yenileme sürecindeyiz. Yılların Android Developer’ı olarak benden istenen ilk iş, tabii ki mobil push notification entegrasyonuydu.

Bunu Vue.js kullanarak, Flutter & Dart kodunun push notification ayrıntılarına bakıp baştan yazmak… Hiç Vue.js, Flutter bilmeden girdiğim bu zorlu yolculuk; benim gibi zorlukları seven biri için en güzel challenge’lardan biriydi. Bu süreçte nasıl başarısız olup saçma sapan vakit kaybettiğimi, sonra da dokümanlarda bir eksiği nasıl fark ettiğimi bu yazıda okuyacaksınız.


Mobil uygulamalara push notification entegre etme süreci, bildiğiniz üzere birkaç adımdan oluşuyor:

  • Cihaza özel bildirim gönderebilmek için cihazın işletim sistemi özel numarasını (device identifier) ve cihaz bilgilerini alıp bunları sunucuya iletmek,

  • Firebase Cloud Messaging (FCM) kullanılacaksa iOS, Android veya web için FCM’de bir proje oluşturmak

  • Cihazı FCM’de açtığımız projeye kayıt etmek (register),

  • Kayıt işleminden dönen register token’ı kendi sunucumuza kaydetmek

  • Backend tarafından, istenilen durumlarda bildirim- gönderecek kodu hazırlamak

Adımlar, geliştiriciler için oldukça alışılmış ve basit görünüyor değil mi? Toplanın, yamacıma çökün bakalım; anlatacaklarım var.



Quasar Vue.JS Kullanarak Cihazın Android / iOS Tanımlayıcı Değerine Nasıl Ulaşılır?

Quasar dokümanlarına baktığımda, aslında çok kolay görünen bu işin ufak ve hiçbir yerde değinilmeyen bir hilesi olduğunu fark ettim ki bu durum bana günlerce zor anlar yaşattı. Ecel terleri döktüm, kovulacağımı sandım, hayata küsüp depresyonlara girdim ancak sonra tekrar toparlandım.

Farklı duygusal ifadeler çizilmiş beş kahverengi yumurta, cam bir yumurta kutusunda yan yana dizilmiş.

Fotoğraf: Tengyart / Unsplash

Öncelikle, Quasar’ın görevi bu değildi. Peki, Quasar’ın görevi nedir; hatta Quasar nedir, oradan başlayalım: Bir web geliştiricisi olarak birçok çeşitte, hızlı bir şekilde farklı ekran boyutlarına uyumlu web siteleri ve/veya uygulamalar oluşturmanıza olanak tanıyan; MIT lisanslı, açık kaynaklı Vue.js tabanlı bir kütüphanedir.

Quasar teknolojisiyle oluşturabileceğiniz uygulamalar ve/veya web siteleri:

  • SPA’lar (Tek Sayfa Uygulaması)

  • SSR (Sunucu Tarafı İşlenen Uygulama + isteğe bağlı PWA istemcisi devralma)

  • PWA’lar (Progresif Web Uygulaması)

  • BEX (Tarayıcı Uzantısı)

  • Mobil Uygulamalar (Cordova veya Capacitor aracılığıyla Android, iOS…)

  • Çok Platformlu Masaüstü Uygulamaları (Electron kullanarak)

Quasar’ın sloganı şudur: “Kodu bir kez yazın ve aynı anda bir web sitesi, mobil uygulama ve/veya Electron uygulaması olarak dağıtın.” Evet; Quasar, tek bir kod tabanı kullanarak rekor sürede bir uygulama geliştirmenize yardımcı olur ve en iyi uygulamalar, son derece hızlı Quasar web bileşenleriyle desteklenir.

“İyi, hoş ama Quasar, cihazların kamera, konum, cihaz bilgileri… gibi yerli (native) özelliklerine erişemiyor.”

İşte burada da imdadımıza Capacitor yetişiyor.

“Capacitor, web uygulamalarını mobil cihazlara dağıtmak için kullanılan bir platformlar arası yerel çalışma zamanı dır. Ionic tarafından geliştirilen Capacitor, Cordova’nın modern bir halefi olarak tasarlanmıştır.”

Dizüstü bilgisayarın önünde oturan, ekrana bakarak hayal kırıklığı ve şaşkınlık ifadesi taşıyan kıvırcık saçlı kadın.

Fotoğraf: Yan Krukau / Pexels

Sonuç olarak: Cordova ve onun üzerine inşa edilmiş Capacitor apileri, yerel cihaz özellikleri ile iletişime geçmemizi sağlıyordu. İşlemler, Quasar ve Capacitor dokümanlarına bakıldığında aslında çok basit görünüyordu.

  • Projeye Capacitor ekle

bash
quasar mode add capacitor
  • Projeye Capacitor’ün Device API’sini ekle

bash
npm install @capacitor/device
  • Senkronize işlemi yap

bash
npx cap sync
  • Gerekli kodu yaz

xml
<template>
  <div>
    <div>Model: {{ model }}</div>
    <div>Manufacturer: {{ manufacturer }}</div>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
import { Device } from '@capacitor/device'

export default {
  setup () {
    const model = ref('Please wait...')
    const manufacturer = ref('Please wait...')

    onMounted(() => {
      Device.getInfo().then(info => {
        model.value = info.model
        manufacturer.value = info.manufacturer
      })
    })

    return {
      model,
      manufacturer
    }
  }
}
</script>
  • Çalıştır…

bash
quasar dev -m capacitor -T android

“Eee, olmadı bu?”

İşte günlerce bu döngüde debelendim. Sildim, baştan yaptım, olmadı. Sildim, başka makaleler takip ederek başka yollardan tekrar yaptım, yine olmadı. Cordova ekledim olmadı. Hâlihazırdaki projede bazı sürümler eski kalmıştır; yeni, bomboş, güncel projede deneyeyim bakayım dedim, yine olmadı…”

Aldığım hataya da bakın:

vbnet
Uncaught (in promise) Error: "Device" plugin is not implemented on android
    at createPluginMethod (runtime.js:86:23)
    at runtime.js:93:32
    at async logDeviceInfo (SearchMovie.vue:58:20)

Uncaught (in promise) Error: “Device” plugin is not implemented on Android.

Ne demek ya “Not implemented,” ekledik işte resmî dokümanın ne istiyorsa, daha ne!

İnternette saatlerce bu hatayı aradım. Çok az sonuç çıktı. Çıkan sonuçlardan doğru dürüst bir sonuca ulaşamadım; çıldırdım, kendimi kaybettim. Kaç iş günü heba ettim bilmiyorum. Bu saatten sonra da kimse bir süre bana cihaz kimlik bilgisi (Device id) demesin kardeşim!

Yazılımcı masasında oturmuş, kırılmış monitör ekranına bakarak düşünceli bir ifadeyle kollarını kavuşturmuş.

ChatGPT tarafından oluşturulan görsel — kaynak ve telif hakkı yazara aittir.

‘Device’ plugin is not implemented on Android hatası rüyalarımda bile dönüp duruyordu. Bir an içimde bir karıncalanma hissettim. Kendi kendime, “Ekledim sanıyorum ama eklemedim mi acaba?” diye düşündüm. Bir şeyi eksik yapıyordum ve bu, dokümanda da kesinlikle yazmıyordu. Sonra aklıma bir fikir geldi: Ben capacitor’ün plugin veya API’lerini sadece app level’da ekliyordum. Acaba bunu Android için de ayrı bir yere mi eklemek gerekiyordu?

Serden gelen yılların Androidciliği sayesinde biliyorum ki bir genel ayar (configurasyon) sayfası olmalı. ‘quasar.config.js’ dosyasına baktım ama bu, daha genel bir ayar sayfasıydı. Aslında aradığım dosya ‘package.lock’ dosyasıydı. Projede gördüğüm kadarıyla iki tane dosya vardı ve sadece birinin ‘dependencies’ (bağımlılık) bölümünde capacitor ile ilgili bağımlılıklar yazıyordu.

json
{
  "name": "com.alp.movie",
  "version": "0.0.1",
  "description": "A Movie App",
  "productName": "Movie App",
  "author": "AlparslanDev <alp.develioglu@gmail.com>",
  "scripts": {
    ...
  },
  "dependencies": {
    "@capacitor/android": "^5.7.0",
    "@capacitor/core": "^5.0.0",
    "@capacitor/device": "^5.0.7",
    "@capacitor/ios": "^5.7.0",
    "@quasar/extras": "^1.16.4",
    "axios": "^1.6.5",
    "install": "^0.13.0",
    "npm": "^10.4.0",
    "pinia": "^2.0.11",
    "quasar": "^2.8.0",
    "vue": "^3.2.29",
    "vue-i18n": "^9.0.0",
    "vue-router": "^4.0.12"
  }
}
json
{
  "name": "com.alp.movie",
  "version": "0.0.1",
  "description": "A Movie App",
  "author": "AlparslanDev <alp.develioglu@gmail.com>",
  "private": true,
  "dependencies": {
    "@capacitor/android": "^5.0.0",
    "@capacitor/app": "^5.0.0",
    "@capacitor/cli": "^5.0.0",
    "@capacitor/core": "^5.0.0"
  }
}

‘Acaba?’ diye düşündüm. Olabilir mi? İkisinin de dosya yollarına baktım ve gördüm ki “@capacitor/device”: “5.0.7” satırının bulunduğu dosya, projenin genel package.lock dosyasıydı. Yazmayan dosya ise src-capacitor/android dosya yolunda bulunuyordu. Hatamız da ‘Device’ plugin is not implemented on Android olunca “Galiba yakaladım,” dedim.

O anki heyecanımı anlatamam: Askerliğin son günü akşamında ablamın ve eniştemin beni almaya gelmelerini; 30.000’inci olduğum YGS (üniversitelere giriş sınavının 2011'deki ismi) sınav sonucunun açıklanmasını ya da 63 kilometrelik Kapadokya Ultra’nın (ultra patika koşusu) son metrelerini beklerken yaşadığım heyecan gibi… Neyse, abarttım biraz, konuya dönüyorum:

cd komutu ile src-capacitor/android dosyasını terminal üzerinden açtım. Yukarıda bahsettiğim komutları sırasıyla tekrar çalıştırdım:

bash
npm install @capacitor/device
npx cap sync

Tabiiki oldu. Başarı bir kez daha benim olmuştu.

Deniz kıyısında ayakta duran, kolları yaygın şekilde açan kadın başarı ve özgürlük anlamını temsil ediyor.

Fotoğraf: Ryan Moreno / Unsplash

Önceki yazıda övdüğüm dokümanlar beni yarı yolda bırakmıştı. Yok senin eksiğin var bunu bilmeden elinin hamuruyla bu işlere girmeseydin keşke diyecekseniz buyrun yorumlarda kapışalım.

Push Notification entegrasyonunun tamamını tek yazıya sığdıramayacağım için şimdilik bu yazıyı sonlandırdım. Yeni yazılarda buluşmak üzere

Asıl push notification yazım yayında: Vue.js ve Quasar ile Firebase Üzerinden Mobil Bildirim Entegrasyonu: Detaylı Kılavuz

Sevgileerr