Merhaba arkadaşlar,
Bugün dersimizde sizlere Firebase kütüphanesi kullanarak Firebase Cloud Storage işleminin nasıl yapılacağını anlatacağım. Firebase ile ilgili realtime database kullanımını bu dersimizde , firebase kullanarak chat uygulaması yapımını bu dersimizde ve authentication kullanımını da bu dersimiz de ayrıntılı bir şekilde anlatmıştım. Fotoğraf veya video gibi içerikleri kolayca depolamak ve sunmak isteyen ortamlarda Android Firebase Storage özelliği kullanılır. Şimdi Android Firebase Storage adımlarını incelemeye başlayalım.
Android Firebase Storage
Diğer derslerde olduğu gibi öncelikle kullanacağımız yapıyı projemize entegre etmemiz gerekiyor. Android Studio da Firebase->Storage->Upload and download a file with Firebase Storage seçeneğini tıklayıp ; gerekli adımları izledikten sonra ilgili kütüphaneleri indirmesini bekliyoruz. En son connected ve dependencies set up correctly yazısını almamız gerekiyor. Bu işlemlerin aynılarını Firebase Realtime Database ve Authentication için de gerçekleştiriyoruz.
Uygulamamızda kullanacağımız gerekli kütüphanelerde indirdikten sonra Firebase Database ve Firebase Authentication için gerekli kütüphaneleri de projemize entegre ediyoruz. Daha önce bahsettiğim gibi bu modüllerden diğer derslerimizde ayrıntılı olarak anlattığım için bu dersimizde daha çok Firebase Storage üzerinde duracağım. Daha sonra console firebase sitesine girip kurallar kısmını kontrol ediyoruz aşağıdaki şekilde bir yapı yoksa değiştiriyoruz. Kod kısmına baktığımızda storage da sisteme yazma ve okuma işlemlerini firebase sistemine kayıtlı olan kullanıcılar için yetkilendiriyoruz.
service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } }
Uygulamamızda login ve register ekranları olacak kullanıcı eğer sisteme kayıt olmadıysa register olabilecek daha sonra karşısına gelen ekranda sisteme kayıtlı olan kullanıcıların e-posta adresleri ve resimlerini görüntüleyebilecek. Ayrıca profil kısmından yine sisteme kayıtlı kullanıcılar istedikleri resmi seçip sisteme yükleyebilecekler. Firebase storage kullanmamızın nedeni; resimleri sisteme yükleyebilmek daha sonradan da çekip gösterebilmek.
Uygulamamızda ilk çalışacak olan sınıf FirstActivity kodları aşağıdadır. Kodları incelersek eğer; bu activity çalıştığında kullanıcı daha önceden sisteme kayıt olduysa otomatik olarak UserListActivity adını verdiğimiz sınıfa yönlendiriyoruz. Giriş için işlemlerini gerçekleştirdiğimiz kodlar da mevcut ayrıca kayıt yapabilmesi içinde RegisterActivity e yönlendirme yapıyoruz. Login için signInWithEmailAndPassword methodunu kullanıyoruz kullanıcıdan e-posta ve şifre alıyor daha sonra doğrulama yapıyor eğer girilen bilgilere göre kayıtlı bir kullanıcı var ise yine UserListActivity sayfasına yönlendiriyoruz.
FirstActivity.java
package com.mobilhanem.firebasestorageapp; import android.content.Intent; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; public class FirstActivity extends AppCompatActivity { private FirebaseAuth mAuth; private FirebaseUser firebaseUser; private Button buttonLogin; private EditText editTextUserName; private EditText editTextUserPassword; private TextView txtRegister; private String userName; private String userPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); buttonLogin = (Button)findViewById(R.id.buttonLogin); editTextUserName = (EditText)findViewById(R.id.editTextUserName); editTextUserPassword = (EditText)findViewById(R.id.editTextUserPassword); txtRegister = (TextView) findViewById(R.id.txtRegister); mAuth = FirebaseAuth.getInstance(); firebaseUser = mAuth.getCurrentUser(); // authenticated user if(firebaseUser != null){ // check user session Intent i = new Intent(FirstActivity.this,UserListActivity.class); startActivity(i); finish(); } txtRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this,RegisterActivity.class); startActivity(intent); } }); buttonLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { userName = editTextUserName.getText().toString(); userPassword = editTextUserPassword.getText().toString(); if(userName.isEmpty() || userPassword.isEmpty()){ Toast.makeText(getApplicationContext(),"Lütfen gerekli alanları doldurunuz!", Toast.LENGTH_SHORT).show(); }else{ loginFunc(); } } }); } private void loginFunc() { mAuth.signInWithEmailAndPassword(userName,userPassword).addOnCompleteListener(FirstActivity.this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if(task.isSuccessful()){ Intent i = new Intent(FirstActivity.this,UserListActivity.class); startActivity(i); finish(); } else{ // hata Toast.makeText(getApplicationContext(),task.getException().getMessage(),Toast.LENGTH_SHORT).show(); } } }); } }
FirstActivity ile ilgili ekran görüntüsü aşağıdadır. Zaten uygulamanın kaynak kodlarını indirip çalıştırdığınızda daha net bir şekilde göreceksiniz ve tam olarak nasıl çalıştığını daha iyi anlayacaksınız.
Kayıt ol a tıkladığımızda RegisterActivity sayfası açılmaktadır. Kodlara baktığımızda createUserWithEmailAndPassword method kullanıcı dan e-posta ve şifre almaktadır Firebase Authentication işlemini gerçekleştirdiğimizde eğer herhangi bir sıkıntı yok ise onComplete methodunda kontrolleri yaptıktan sonra User modelimize kullanıcının e-posta adresini ve FirebaseAuth.getInstance().getCurrentUser().getUid() ile eriştiğimiz register olan her kullanıcıya özel üretilen uid değerini kaydediyoruz. Firebase Realtime Database özelliğini kullanarak da oluşturduğumuz bu User modelini veri tabanına kayıt ediyoruz.
RegisterActivity.java
package com.mobilhanem.firebasestorageapp; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; public class RegisterActivity extends AppCompatActivity { private EditText registerUserName; private EditText registerPassword; private FirebaseAuth mAuth; private String userName; private String userPassword; private DatabaseReference databaseReference; private Button buttonRegister; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); mAuth = FirebaseAuth.getInstance(); registerUserName = (EditText)findViewById(R.id.registerUserName); registerPassword = (EditText)findViewById(R.id.registerPassword); buttonRegister = (Button)findViewById(R.id.buttonRegister); buttonRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { userName = registerUserName.getText().toString(); userPassword = registerPassword.getText().toString(); if(userName.isEmpty() || userPassword.isEmpty()){ Toast.makeText(getApplicationContext(),"Lütfen gerekli alanları doldurunuz!", Toast.LENGTH_SHORT).show(); }else{ registerFunc(); } } }); } private void registerFunc() { mAuth.createUserWithEmailAndPassword(userName,userPassword) .addOnCompleteListener(RegisterActivity.this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(Task<AuthResult> task) { if(task.isSuccessful()){ String uId = FirebaseAuth.getInstance().getCurrentUser().getUid(); databaseReference = FirebaseDatabase.getInstance().getReference("users/"+uId); User user = new User(userName,uId); databaseReference.setValue(user); Intent i = new Intent(RegisterActivity.this,UserListActivity.class); startActivity(i); finish(); } else{ Toast.makeText(getApplicationContext(),task.getException().getMessage(),Toast.LENGTH_SHORT).show(); } } }); } }
RegisterActivity ile ilgili ekran görüntüsü aşağıdadır.
Register işleminden sonra realtime database kaydettiğimiz User modelleri console firebase girdiğimizde aşağıdaki gibi gözükecektir. “users” referansı altında kayıtlı olan kullanıcıları görmekteyiz.
Login veya Register olduktan sonra UserListActivity sayfamıza yönleniyoruz; ilgili kaynak kodları aşağıda yer almaktadır. Kodlara baktığımızda Firebase Database de kayıtlı olan User modellerini çekip listede gösteriyoruz. ListView yerine third party bir kütüphane olan JazzyListView kullandık animasyonu ve görselliği daha efektif olduğundan. Ayrıca bu sayfada option menuden profil kısmına bastığımızda ProfileActivity sayfasına yönleniyoruz.
UserListActivity.java
package com.mobilhanem.firebasestorageapp; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.Toast; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.ValueEventListener; import com.twotoasters.jazzylistview.JazzyListView; import com.twotoasters.jazzylistview.effects.SlideInEffect; import java.util.ArrayList; import java.util.List; public class UserListActivity extends AppCompatActivity { private FirebaseAuth firebaseAuth; private DatabaseReference databaseReference; private JazzyListView list; private CustomAdapter customAdapter; private List<User> personList; private ProgressDialog progressDialog; @Override protected void onResume() { super.onResume(); if(customAdapter!=null){ customAdapter.notifyDataSetChanged(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.profile_item: Intent intent = new Intent(getApplicationContext(),ProfileActivity.class); startActivity(intent); return true; default: return super.onOptionsItemSelected(item); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_list); firebaseAuth = FirebaseAuth.getInstance(); databaseReference = FirebaseDatabase.getInstance().getReference("users"); list = (JazzyListView) findViewById(R.id.list); personList = new ArrayList<>(); progressDialog = new ProgressDialog(UserListActivity.this); progressDialog.setMessage("Yükleniyor..."); progressDialog.setCancelable(false); progressDialog.show(); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { progressDialog.dismiss(); personList.clear(); for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { User userObj = postSnapshot.getValue(User.class); personList.add(userObj); } customAdapter = new CustomAdapter(getApplicationContext(),personList); list.setAdapter(customAdapter); list.setTransitionEffect(new SlideInEffect()); } @Override public void onCancelled(DatabaseError databaseError) { progressDialog.dismiss(); Toast.makeText(UserListActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } }); } }
UserListActivity ile ilgili ekran görüntüsü aşağıdadır.
ProileActivity sınıfımıza baktığımızda kullanıcı telefondan istediği resmi seçip uygulamada gösteriyor daha sonra kaydet butonuna bastığımızda Firebase Storage sistemine ilgili resmi kayıt ediyoruz. Burada kayıt ederken aktif olan kullanıcın uid sine göre kayıt işlemini tamamlıyoruz çünkü her kullanıcıya ait resimler unique olmalıdır. StorageReference storageRef = fStorage.getReference().child(“users”).child(mAuth.getCurrentUser().getUid()) bu kod yardımıyla users klasörü altında storage referansını kullanıcıya özel olan uid ile oluşturuyoruz. putFile ile de seçilen resmin Uri yolunu yüklüyoruz bu sayede resmi sisteme direk olarak aktarmış olduk. İlgili resmi çekerken de yine referans adresini alıyoruz daha sonradan getDownloadUrl methodu yardımı ile sistemden resmi çekip ekranda gösteriyoruz. Aşağıdaki ekran görüntüsünde storage kısmına yüklediğimiz resimler gözükmektedir; resimleri kullanıcılar ile ilişkilendirip o şekilde yüklediğimizi unutmayalım.
ProfileActivity.java
package com.mobilhanem.firebasestorageapp; import android.app.ProgressDialog; import android.content.Intent; import android.net.Uri; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; import com.google.firebase.storage.UploadTask; import com.squareup.picasso.Picasso; public class ProfileActivity extends AppCompatActivity { private Button buttonSaveImage; private Button buttonSelectImage; private ImageView imageView; private static final int PICK_IMAGE_REQUEST = 123; private Uri filePath; private FirebaseAuth mAuth; private FirebaseStorage fStorage; private ProgressDialog progressDialog; private Button signOutBtn; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) { filePath = data.getData(); try { Picasso.with(ProfileActivity.this).load(filePath).fit().centerCrop().into(imageView); } catch (Exception e) { e.printStackTrace(); } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); mAuth = FirebaseAuth.getInstance(); fStorage = FirebaseStorage.getInstance(); buttonSaveImage = (Button) findViewById(R.id.buttonSaveImage); buttonSelectImage = (Button) findViewById(R.id.buttonSelectImage); imageView = (ImageView) findViewById(R.id.imageView); progressDialog = new ProgressDialog(ProfileActivity.this); progressDialog.setMessage("Yükleniyor..."); progressDialog.setCancelable(false); progressDialog.show(); StorageReference storageRef = fStorage.getReference().child("users").child(mAuth.getCurrentUser().getUid()); storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { progressDialog.dismiss(); Picasso.with(ProfileActivity.this).load(uri).fit().centerCrop().into(imageView); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { progressDialog.dismiss(); Toast.makeText(ProfileActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show(); } }); buttonSelectImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Resim Seçiniz"), PICK_IMAGE_REQUEST); } }); signOutBtn = (Button)findViewById(R.id.buttonSignOut); signOutBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mAuth.signOut(); Intent intent = new Intent(getApplicationContext(), FirstActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); finish(); startActivity(intent); } }); buttonSaveImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(filePath!=null){ progressDialog = new ProgressDialog(ProfileActivity.this); progressDialog.setMessage("Yükleniyor..."); progressDialog.setCancelable(false); progressDialog.show(); StorageReference storageRef = fStorage.getReference().child("users").child(mAuth.getCurrentUser().getUid()); storageRef.putFile(filePath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { progressDialog.dismiss(); Toast.makeText(ProfileActivity.this, "Fotoğraf başarılı bir şekilde kaydedildi.", Toast.LENGTH_SHORT).show(); imageView.setImageBitmap(null); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { progressDialog.dismiss(); Toast.makeText(ProfileActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show(); } }); } } }); } }
ProfileActivity ile ilgili ekran görüntüsü aşağıdadır.
build.gradle kısmı aşağıdaki gibidir. Uygulamada resimleri görüntüleyebilmek için Picasso ve Glide kütüphanelerinden yararlandık zaten performans açısından en çok önerilen ve kullanılan kütüphaneler bunlar olduğu için kod kısımda yer almaktadır. Dilerseniz Glide ile resimleri görüntüleyin dilerseniz Picasso ile kod satırından yorum kısmını açıp kullanabilirsiniz.
build.gradle
apply plugin: 'com.android.application' android { compileSdkVersion 26 buildToolsVersion "26.0.1" defaultConfig { applicationId "com.mobilhanem.firebasestorageapp" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } repositories { mavenCentral() // jcenter() works as well because it pulls from Maven Central } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.google.firebase:firebase-storage:10.0.1' compile 'com.google.firebase:firebase-auth:10.0.1' compile 'com.google.firebase:firebase-database:10.0.1' compile 'com.squareup.picasso:picasso:2.5.1' compile 'com.twotoasters.jazzylistview:library:1.2.1' compile 'com.android.support:cardview-v7:23.0.0' compile 'com.github.bumptech.glide:glide:3.7.0' testCompile 'junit:junit:4.12' } apply plugin: 'com.google.gms.google-services'
Listemizi doldurmak için kullandığımız adapter sınıfımızda aşağıdadır.
CustomAdapter.java
package com.mobilhanem.firebasestorageapp; import android.content.Context; import android.graphics.Bitmap; import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SimpleTarget; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; import java.util.List; /** * Created by alper_beyler on 9.10.2017. */ public class CustomAdapter extends ArrayAdapter<User> { private Context context; private List<User> userList; public CustomAdapter(Context context, List<User> users) { super(context, 0, users); this.context = context; this.userList = users; } @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { View v = convertView; final ViewHolder holder; if (v == null) { LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.custom_item, null); holder = new ViewHolder(); holder.userName = (TextView) v.findViewById(R.id.userNameTxt); holder.userImage = (ImageView) v.findViewById(R.id.userImage); v.setTag(holder); } else { holder = (ViewHolder) v.getTag(); } User user = userList.get(position); holder.userName.setText(user.getUserName()); FirebaseStorage fStorage = FirebaseStorage.getInstance(); StorageReference storageRef = fStorage.getReference().child("users").child(user.getuId()); storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { //Picasso.with(context).load(uri).fit().centerCrop().into(holder.userImage); Glide.with(context) .load(uri) .asBitmap() .centerCrop() .into(new SimpleTarget<Bitmap>(200,200) { @Override public void onResourceReady(Bitmap resource,GlideAnimation glideAnimation) { holder.userImage.setImageBitmap(resource); } }); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { } }); return v; } static class ViewHolder { TextView userName; ImageView userImage; } }
Ever arkadaşlar Firebase Storage Kullanımını da sizlere anlatmaya çalıştım. Sıfırdan kendiniz bir proje oluşturup buradaki adımları uygulamanız çok daha yararlı olacaktır hem kendi Firebase sisteminizi daha net gözlemlersiniz ben kendi gmail hesabımla entegre olup kodları oluşturduğum için veritabanı kısmını göremeyeceksiniz o yüzden kendiniz bir proje oluşturup deneyin. Firebase ile ilgili bir çok ders serisi anlattım diğer dersimizde Firebase Dynamic Link konusuna başlamayı düşünüyorum.
Tüm Android Ders, Proje ve Kaynak Kodlar için tıklayınız.
Mobilhanem.com üzerinden anlattığımız android uygulama geliştirme derslerine devam edeceğiz. Konu hakkında sorunuzu yorum alanından sorabilirsiniz. Konu dışı sorularınızı ve tüm yazılımsal sorularınızı sorucevap.mobilhanem.com sitemizden de sorabilirsiniz.
Bir dahaki dersimizde görüşmek dileğiyle..