Ionic ile Uygulama Geliştirme (+Firebase)

betül ünver
BilgeAdam Teknoloji
7 min readDec 20, 2019

--

Bu yazıda Ionic Framework’ünü kullanarak ToDo List tarzında uygulama nasıl geliştirilir onu anlatacağım. Uygulamaya Firebase ile entegre ederek Crud işlemleri nasıl yapılır onu göreceğiz.

Projemizi Oluşturalım

Eğer daha önce Ionic kurulumu yapmadıysanız, buradaki adımları izleyebilirsiniz.

Proje klasörünü oluşturup , komut satırında klasörün bulunduğu dizine geliyorum.

ionic start ToDoList

Bu kısımda bize hangi framework’ü kullanacağımızı soruyor. Angular ‘ı seçiyorum.

Daha sonra bana template olarak ne kullanacağımı soruyor. 5 tane seçenek sunuyor bize. İhtiyacınıza göre istediğini seçebilirsiniz. Bu aşamada ben blank olanı seçeceğim.

Uygulama dosyalarının bulunuğu dizine geçip projeyi başlatıyorum.

cd ToDoList
ionic serve

Proje localhost:8100 portunda açıldı ve aşağıdaki gibi gözüküyor.

Projeyi, Ionic Lab üzerinde çalıştırmak için Ctrl+ C komutu ile durdurup ionic serve -lab komutuyla tekrar başlatıyorum. Böylece hem ios hem android ortamında nasıl gözüktüğümü aynı anda görebiliyor olacağım. Lab için 8200 portunu kullanırken yine local için 8100 portunu kullanıyor.

ionic-lab

Firebase Uygulamasını Oluşturalım

Proje oluşturabilmek için konsola gidelim.Daha sonra “Başlamak için uygulama ekleyin” seçeneklerinden web’i tıklayarak uygulama oluşturalım. Ionic uygulamamız ile firebase uygulamamızın haberleşmesini sağlayacak kimlik bilgileri artık elimizde !

Hadi şimdi bu bilgileri Ionic projemizin içine ekleyelim. Bunun için /src klasörünün altında /environments içinde bulunan environment.ts dosyasını bu formatta olacak şekilde düzenleyelim.

export const environment = {
production: false,
firebase: {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
databaseURL: "YOUR_DATABASE_URL",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_SENDER_ID"
}
};

Not : Proje başlatılırken bu bilgiler ile bağlanmasını sağlamak için initializeApp olarak set etmemiz gerekiyor.

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
AngularFireModule.initializeApp(environment.firebase), // imports firebase/app
AngularFirestoreModule, // imports firebase/firestore
AngularFireAuthModule, // imports firebase/auth
AngularFireStorageModule, // imports firebase/storage
],
providers: [
StatusBar,
SplashScreen,
ImagePicker,
WebView,
{ provide: FirestoreSettingsToken, useValue: {} },
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})

Firebase Authentication

Kimlik doğrulaması için giriş yöntemi belirlememiz gerekiyor. Bunun için sol tarafataki menüden Authentication tıklayalım. Oturum açma yöntemini ayarla butonundan sağlayıcı olarak E-Posta / Parola şeçeneğini etkinleştirelim.

Servisler

src/app altına services klasörü oluşturalım. Bu klasörde CRUD işlemleri için gerekli fonksiyonları ekleyeceğiz. Authentication ile ilgili olanlar için auth.service.ts ve tüm CRUD işlemleri için firebase.service.ts dosyalarını oluşturacağım. Bunu için terminali açıyorum. Oluşturduğumuz services klasörünün dizinine geçiyorum .

ionic g service auth veionic g service firebase komutları ile dosyaları oluşturuyorum.

Ionic projemiz ile firebase uygulamamız arasında bağlantı kurup haberleşmesi için angularfire componentine ihtiyacımız var o yüzden bunu npm üzerinden indiriyorum.

npm install @angular/fire firebase --save

Gelelim şimdi firebase kütüphanesi ile nasıl giriş ve kayıt işlemlerini yapıyoruz ona bakalım.

Firebase bize sunduğu createUserWithEmailAndPassword ve signInWithEmailAndPassword metotlarını kullanacağız. Bunun için sayfaya kütüphaneyi çağıralım.

Auth.service.ts

import { Injectable } from "@angular/core";
import * as firebase from 'firebase/app';
import { FirebaseService } from './firebase.service';
import { AngularFireAuth } from '@angular/fire/auth';

@Injectable({
providedIn: 'root'
})
export class AuthService {

constructor(
private firebaseService: FirebaseService,
public afAuth: AngularFireAuth
){}

doRegister(value){
return new Promise<any>((resolve, reject) => {
firebase.auth().createUserWithEmailAndPassword(value.email, value.password)
.then(
res => resolve(res),
err => reject(err))
})
}

doLogin(value){
return new Promise<any>((resolve, reject) => {
firebase.auth().signInWithEmailAndPassword(value.email, value.password)
.then(
res => resolve(res),
err => reject(err))
})
}

doLogout(){
return new Promise((resolve, reject) => {
this.afAuth.auth.signOut()
.then(() => {
this.firebaseService.unsubscribeOnLogOut();
resolve();
}).catch((error) => {
reject();
});
})
}
}

Authentication için gerekli olan metotları yazdık. UI tarafı için componentleri hazırlayalım şimdi.

Component Hazırlayalım

Terminale gelip src/app klasörünün altına componentimi oluşturuyorum.

ionic g page login

login.page.html

<form class="form" [formGroup]="validations_form" (ngSubmit)="tryRegister(validations_form.value)">
<ion-item>
<ion-label position="floating" color="primary">Email</ion-label>
<ion-input type="text" formControlName="email"></ion-input>
</ion-item>
<div class="validation-errors">
<ng-container *ngFor="let validation of validation_messages.email">
<div class="error-message" *ngIf="validations_form.get('email').hasError(validation.type) && (validations_form.get('email').dirty || validations_form.get('email').touched)">
{{ validation.message }}
</div>
</ng-container>
</div>

<ion-item>
<ion-label position="floating" color="primary">Password</ion-label>
<ion-input type="password" formControlName="password"></ion-input>
</ion-item>
<div class="validation-errors">
<ng-container *ngFor="let validation of validation_messages.password">
<div class="error-message" *ngIf="validations_form.get('password').hasError(validation.type) && (validations_form.get('password').dirty || validations_form.get('password').touched)">
{{ validation.message }}
</div>
</ng-container>
</div>

<ion-button class="submit-btn" expand="block" type="submit" [disabled]="!validations_form.valid">Register</ion-button>
<label class="error-message">{{errorMessage}}</label>
<label class="success-message">{{successMessage}}</label>
</form>

login.page.ts

export class LoginPage implements OnInit {
validations_form: FormGroup;
errorMessage: string = '';
validation_messages = {
'email': [
{ type: 'required', message: 'Email is required.' },
{ type: 'pattern', message: 'Please enter a valid email.' }
],
'password': [
{ type: 'required', message: 'Password is required.' },
{ type: 'minlength', message: 'Password must be at least 5
characters long.' }
]};
constructor(
private authService: AuthService,
private formBuilder: FormBuilder,
private router: Router
) { }
ngOnInit() {
this.validations_form = this.formBuilder.group({
email: new FormControl('', Validators.compose([
Validators.required,
Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')
])),
password: new FormControl('',Validators.compose([
Validators.minLength(5),
Validators.required
])),
});
}
tryLogin(value) {
this.authService.Login(value).then(res => { this.router.navigate(["/home"]);}, err => {
this.errorMessage = err.message;
console.log(err)
})
}
goRegisterPage() {
this.router.navigate(["/register"]);
}}

Diğer componentler için kaynak kodlarına buradan ulaşabilirsiniz.

Firebase CRUD İşlemleri

Firebase crud metotlarını kullanarak ionic projemize nasıl uygulayacağımıza bakalım şimdi de..

Create

Crud işlemlerinin firebase.service.ts dosyasında barındıracağımızı söylemiştik. Yeni yazacağımız metotları oraya ekleyeceğiz.

Yeni bir task oluşturmaya çalışacağız. Bunun için firebase.service.ts servisine gelip createTask() adında metot oluşturalım.

createTask(value){
return new Promise<any>((resolve, reject) => {
let currentUser = firebase.auth().currentUser;
this.afs.collection('people').doc(currentUser.uid).collection('tasks').add({
title: value.title,
description: value.description,
image: value.image
})
.then(
res => resolve(res),
err => reject(err)
)
})
}

Yeni oluşturulacak taskın giriş yapmış kullanıcı üzerinden kayıt yapması için firebase.auth().currentUser yöntemini kullanıyoruz.

Firebase Fotoğraf Yükleme

Her task için bir fotoğraf kaydetmiş olacağız. Image Picker ile galeriden seçilen fotoğrafın firebase Cloud Storage ‘e nasıl kaydedilir ona bakalım.

Image Picker native plugin olduğu için ve ionic native özelliklere cordova ile erişebildiği için indirmemiz gerekiyor. Terminale gelelim ve daha sonra aşağıdaki kodları yazalım.

>ionic cordova plugin add cordova-plugin-telerik-imagepicker — variable PHOTO_LIBRARY_USAGE_DESCRIPTION=”your usage message”

>npm install --save @ionic-native/image-picker@beta

storage değişkeni tanımlıyoruz.

let storageRef = firebase.storage().ref();
let imageRef = storageRef.child('image').child('imageName');

ImagePicker ‘dan gelen url’yi base64 url formatına dönüştürmemiz lazım.

encodeImageUri(imageUri, callback) {
var c = document.createElement('canvas');
var ctx = c.getContext("2d");
var img = new Image();
img.onload = function () {
var aux:any = this;
c.width = aux.width;
c.height = aux.height;
ctx.drawImage(img, 0, 0);
var dataURL = c.toDataURL("image/jpeg");
callback(dataURL);
};
img.src = imageUri;
};

putString(image64, 'data_url') metodu ile firebase eklenen fotoğrafa atanan url’yi alacağız. Daha sonra bu url’yi kullanarak , snapshot.ref.getDownloadURL() metodu ile fotoğrafa erişebileceğiz.

uploadImage(imageURI, randomId){
return new Promise<any>((resolve, reject) => {
let storageRef = firebase.storage().ref();
let imageRef = storageRef.child('image').child(randomId);
this.encodeImageUri(imageURI, function(image64){
imageRef.putString(image64, 'data_url')
.then(snapshot => {
snapshot.ref.getDownloadURL()
.then(res => resolve(res))
}, err => {
reject(err);
})
})
})
}

Read

Oluşturulan taskları listeletelim. Tüm kullanıcıların task’larını almak için getTasks() adında metot oluşturalım.

getTasks(){
return new Promise<any>((resolve, reject) => {
this.afAuth.user.subscribe(currentUser => {
if(currentUser){
this.snapshotChangesSubscription = this.afs.collection('people').doc(currentUser.uid).collection('tasks').snapshotChanges();
resolve(this.snapshotChangesSubscription);
}
})
});
}

snapshotChanges() metodunu kullanmak öenmli çünkü bu metot bize her task için bir ID döndürüyor. Delete, update gibi işlemleri ID üzerinden yapacağımız için önem teşkil ediyor.

Update

updateTask() metodu oluşturacağız. Bu metot içine task’ın id’sini ve yeni değerlerini alacak.

updateTask(taskKey, value){
return new Promise<any>((resolve, reject) => {
let currentUser = firebase.auth().currentUser;
this.afs.collection('people').doc(currentUser.uid).collection('tasks').doc(taskKey).set(value)
.then(
res => resolve(res),
err => reject(err)
)
})
}

Delete

Silme işleminde bilmemiz gereken tek şey ID’si .deleteTask() metodu ile silme işlemini gerçekleştirelim.

deleteTask(taskKey){
return new Promise<any>((resolve, reject) => {
let currentUser = firebase.auth().currentUser;
this.afs.collection('people').doc(currentUser.uid).collection('tasks').doc(taskKey).delete()
.then(
res => resolve(res),
err => reject(err)
)
})
}

Uygulama Ekranları

login.page.html
register.page.html
home.page.html
new-task.page.html

Sonuç

Uygulaması, birçok kullanıcı tarafından yüklenen geliştiricilerin , kayıt — oturum bilgilerini tutma, uygulamaların kullanım verilerini analiz etme, yeni duyurular yapmak için aynı zamanda kullanıcıya bildirim gönderme, uygulamayı test etme gibi işlemleri rahatlıkla yönetebileceği bir yönetim paneli gerekiyor.

Firebase bu ihtiyaçları karşılayan ücretsiz bir platform.

Diğer yandan hem firmalar hem geliştiriciler aynı uygulamayı tüm platformlarda çalıştırabilmek istiyor. “ Write once, run anywhere.” mantığı ile çıkan Ionic, multiple platformlarda (IOS,Android,Desktop, Progressive Web App) tek codebase ile çalışabilmeyi sağlıyor.

Ürün geliştirmesi kolay ve hızlı şekilde çıktı alabileceğiniz bir platform olan Ionic, Firebase entegrasyonu ile pratik bir şekilde uygulamalar geliştirebilirsiniz.

Kaynaklar :

--

--