Ionic ile Uygulama Geliştirme (+Firebase)
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.
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ı
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 :