FirebaseUI android was introduced very recently by Google. According to Google, FirebaseUI is a library that allows developers to build native Mobile Apps quickly with Firebase by binding common UI views to Firebase references or queries. Currently FirebaseUI android supports ListViews
, GridViews
, and RecyclerViews
.
In this example, we will Integrate Realtime Firebase Database to our Recyclerview using Firebase UI so that the data can be changed dynamically in real time and the Recyclerview gets updated automatically. The following video clearly demonstrates what we are going to achieve in this tutorial:
While its really exciting to see how the data changes dynamically, let us get started and implement it 🙂
[widget id=”text-15″]
FirebaseUI Android using Firebase Database:
The complete source code for this Tutorial can be cloned/downloaded from the github repo link below:
Note:Â For the above project sourcecode to work, you need to replace google-services.json file with your configured file. The steps for configuration are explained below:
To explain about FirebaseUI android, I am going to create an Interesting app called Movie Board in which I am going to save my Favourite movies by adding and rating them. So Let us get started.
1. Adding Firebase to Your Android App:
[widget id=”text-3″]
To get started, you need to create a project in Firebase Console. Go to the following link and create a New Firebase Project. Here I’ve named it as Firebase Database Example. Now if we click on the project we will be taken to the application Overview similar to the image below:
Now click on Add Firebase to your Android app and it will display a pop up asking for package name and SHA1 key of your debug key certificate.
To get SHA1 key, you need to type the following command in your Command Prompt:
keytool -list -v -keystore C:/Users/vamsi/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
Now If you click on ADD APP, the browser automatically downloads google-services.json file which you need to save in your Project’s app module root directory as shown in image below:
[widget id=”text-15″]
Now add the following line to Project’s build.gradle file’s dependencies to include Google Services:
classpath 'com.google.gms:google-services:3.0.0'
Now my Project’s build.gradle file look like:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files // Add this line to include google services classpath 'com.google.gms:google-services:3.0.0' } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
[widget id=”text-3″]
Now modify your app’s build.gradle file so that it references the required library dependencies. Here is the file with libraries I’ve included in this project:
apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion '24' defaultConfig { applicationId "com.coderefer.firebasedatabaseexample" minSdkVersion 16 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:24.0.0' compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha1' testCompile 'junit:junit:4.12' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.android.support:support-annotations:24.0.0' //Libraries I've included compile 'com.google.firebase:firebase-database:9.4.0' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.android.support:cardview-v7:24.0.0' compile 'com.android.support:design:24.0.0' compile 'com.android.support:recyclerview-v7:24.0.0' // Single target that includes all FirebaseUI libraries compile 'com.firebaseui:firebase-ui:0.4.4' } // Add to the bottom of the file apply plugin: 'com.google.gms.google-services'
Now you’ve successfully added Firebase to your Android app.
2. Authenicating Firebase Database:
Next we need Authentication to our Firebase Database so that we can access the data. We will be discussing about Firebase Authentication in our Next Tutorial. For now, we will set up Authentication rules to Public where any user can read and write the Firebase data.
[widget id=”text-15″]
However note that you should configure more secure rules to Firebase Database to restrict your database from unauthorized access.
To change the database rules, click on your project in Firebase console and click on Database Pane on Left as shown in image.
Now click on Rules as shown above. Now replace your default code with the following:
// These rules give anyone, even people who are not users of your app, // read and write access to your database //Remember to change these rules while publishing your app { "rules": { ".read": true, ".write": true } }
FirebaseUI android in brief:
Now let us discuss in brief about FirebaseUI android element which we will be using in this tutorial, i.e., FirebaseRecyclerAdapter. FirebaseRecyclerAdapter has been written to ease the Developer’s burden to dynamically sync the data, repopulate views and deleting unwanted views.
There is also a FirebaseUI android Element for Listviews called as FirebaseListAdapter but since Recyclerview is the recent and preferred one compared to ListView, our tutorial will be focusing on using FirebaseRecyclerAdapter.
To more about RecyclerView, you can refer to our previous article where we’ve discussed in detail about RecyclerView and CardView Implementation.
[widget id=”text-15″]
FirebaseRecyclerAdapter is an abstract class which handles all of the child events at the given Firebase location. It marshals received data into the given class type.
In order to use FirebaseRecyclerAdapter, we create the reference to the object as follows:
FirebaseRecyclerAdapter<ModelClass, ViewHolder> adapter = new FirebaseRecyclerAdapter<>( modelClass, listItemLayout,viewHolderClass, ref);
where the parameter are as explained below:
modelClass – instance of the model class you’ve created
listItemLayout –  represents the layout file of the list item of RecyclerView
viewHolderClass – represents the view Holder class which hold references to all sub-views in a listItemLayout’s instance
ref – Â reference to the Firebase database location where we will put/modify our data.
[widget id=”text-3″]
3. Adding Additional Files required
Before going any further let us configure our common files such as colors.xml, strings.xml and styles.xml.
Here is my colors.xml file:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#9C27B0</color> <color name="colorPrimaryDark">#7B1FA2</color> <color name="colorAccent">#FE3F80</color> <color name="textPrimary">#212121</color> <color name="textSecondary">#727272</color> <color name="white">#fff</color> <color name="background">#dae2e2e2</color> </resources>
[widget id=”text-3″]
Now my strings.xml file consists of following:
<resources> <string name="app_name">Movie Board</string> <string name="movie_name_hint">Enter Movie Name</string> </resources>
Our modified styles.xml file will consist of the following code:
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <!--Defining colors for TextInputLayout's EditText--> <style name="TextLabel" parent="TextAppearance.AppCompat"> <!-- Hint color and label color in FALSE state --> <item name="android:textColorHint">#9575cd</item> <item name="android:textSize">20sp</item> <!-- Label color in TRUE state and bar color FALSE and TRUE State --> <item name="colorAccent">@color/colorAccent</item> <item name="colorControlNormal">#9575cd</item> <item name="colorControlActivated">@color/colorAccent</item> </style> </resources>
[widget id=”text-15″]
5. Creating files required by FirebaseUI android:
From the parameters of FirebaseUI android, we can see that we need a model, a layout for list item and a viewholder class. Let us begin by creating a model class.
Here, I’ve created a package called models and created a model class named Movie.java for my project Movie Board and have written the following code to get and set movie’s name, rating and movie’s logo:
package com.coderefer.firebasedatabaseexample.models; /** * Created by vamsi on 18-Jul-16. */ public class Movie { public String movieName; public String moviePoster; public float movieRating; public Movie(){ } public Movie(String movieName,String moviePoster,float movieRating){ this.movieName = movieName; this.moviePoster = moviePoster; this.movieRating = movieRating; } public String getMovieName() { return movieName; } public void setMovieName(String movieName) { this.movieName = movieName; } public String getMoviePoster() { return moviePoster; } public void setMoviePoster(String moviePoster) { this.moviePoster = moviePoster; } public float getMovieRating() { return movieRating; } public void setMovieRating(float movieRating) { this.movieRating = movieRating; } }
[widget id=”text-3″]
Next we need a list item layout for which I’ve created a Layout file called movie_board_item.xml and wrote the following code:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- A CardView that contains a TextView --> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="5dp" card_view:cardElevation="5dp" card_view:cardCornerRadius="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.2"> <ImageView android:id="@+id/iv_movie_poster" android:layout_width="match_parent" android:src="@drawable/civil_war" android:scaleType="centerCrop" android:layout_height="match_parent"/> <RatingBar android:layout_marginRight="15dp" android:layout_marginBottom="15dp" style="?android:attr/ratingBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:rating="3.5" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:id="@+id/rating_bar" /> </RelativeLayout> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="18sp" android:textStyle="bold" android:text="Captain America Civil War" android:layout_weight=".8"/> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout>
In the above code we used cardviews about which we’ve explained in our previous article.
[widget id=”text-15″]
Next, as discussed previously, we need a ViewHolder class which we’ll be declaring in our MainActivity.java class itself as an inner class.
Now we’ll modify our activity_main.xml as follows:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#dcdbdb"> <TextView android:id="@+id/tv_no_movies" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="No Movies Available Please Enter your fav movie by clicking + button" android:textAlignment="center" android:textSize="18sp"/> <FrameLayout android:id="@+id/frame_container" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:scrollbars="vertical" android:layout_height="match_parent" android:layout_width="match_parent"/> </FrameLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:src="@drawable/ic_add_white_24dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginRight="23dp" android:layout_marginEnd="23dp" android:layout_marginBottom="22dp" /> </RelativeLayout>
Now open MainActivity.java and write the following code:
package com.coderefer.firebasedatabaseexample; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.Log; import android.view.View; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; import android.widget.ImageView; import android.widget.RatingBar; import android.widget.TextView; import com.coderefer.firebasedatabaseexample.adapters.MovieBoardAdapter; import com.coderefer.firebasedatabaseexample.fragments.AddMovieFragment; import com.firebase.ui.database.FirebaseRecyclerAdapter; 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.squareup.picasso.Picasso; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity { //created for firebaseui android tutorial by Vamsi Tallapudi private FloatingActionButton fab; ScaleAnimation shrinkAnim; private RecyclerView mRecyclerView; private StaggeredGridLayoutManager mLayoutManager; private TextView tvNoMovies; //Getting reference to Firebase Database FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference mDatabaseReference = database.getReference(); private static final String userId = "53"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Initializing our Recyclerview mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); tvNoMovies = (TextView) findViewById(R.id.tv_no_movies); //scale animation to shrink floating actionbar shrinkAnim = new ScaleAnimation(1.15f, 0f, 1.15f, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); if (mRecyclerView != null) { //to enable optimization of recyclerview mRecyclerView.setHasFixedSize(true); } //using staggered grid pattern in recyclerview mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); //Say Hello to our new FirebaseUI android Element, i.e., FirebaseRecyclerAdapter FirebaseRecyclerAdapter<Movie,MovieViewHolder> adapter = new FirebaseRecyclerAdapter<Movie, MovieViewHolder>( Movie.class, R.layout.movie_board_item, MovieViewHolder.class, //referencing the node where we want the database to store the data from our Object mDatabaseReference.child("users").child(userId).child("movies").getRef() ) { @Override protected void populateViewHolder(MovieViewHolder viewHolder, Movie model, int position) { if(tvNoMovies.getVisibility()== View.VISIBLE){ tvNoMovies.setVisibility(View.GONE); } viewHolder.tvMovieName.setText(model.getMovieName()); viewHolder.ratingBar.setRating(model.getMovieRating()); Picasso.with(MainActivity.this).load(model.getMoviePoster()).into(viewHolder.ivMoviePoster); } }; mRecyclerView.setAdapter(adapter); fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { getSupportFragmentManager().beginTransaction() .replace(R.id.frame_container, new AddMovieFragment()) .addToBackStack(null) .commit(); //animation being used to make floating actionbar disappear shrinkAnim.setDuration(400); fab.setAnimation(shrinkAnim); shrinkAnim.start(); shrinkAnim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { //changing floating actionbar visibility to gone on animation end fab.setVisibility(View.GONE); } @Override public void onAnimationRepeat(Animation animation) { } }); } }); } @Override public void onBackPressed() { super.onBackPressed(); if (fab.getVisibility() == View.GONE) fab.setVisibility(View.VISIBLE); } //ViewHolder for our Firebase UI public static class MovieViewHolder extends RecyclerView.ViewHolder{ TextView tvMovieName; RatingBar ratingBar; ImageView ivMoviePoster; public MovieViewHolder(View v) { super(v); tvMovieName = (TextView) v.findViewById(R.id.tv_name); ratingBar = (RatingBar) v.findViewById(R.id.rating_bar); ivMoviePoster = (ImageView) v.findViewById(R.id.iv_movie_poster); } } }
[widget id=”text-15″]
The code is commented wherever it is felt necessary.  Next we’ll declare a Fragment so that when we click on Floating action bar, we will get the fragment from which we can add movie name, rating and Movie Poster. Here I’ve declared my fragment as AddMovieFragment.java and wrote the following code:
package com.coderefer.firebasedatabaseexample.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.TextInputEditText; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.RatingBar; import android.widget.Toast; import com.coderefer.firebasedatabaseexample.models.Movie; import com.coderefer.firebasedatabaseexample.R; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; /** * Created by vamsi on 08-Jul-16. */ public class AddMovieFragment extends Fragment implements View.OnClickListener { private DatabaseReference mDatabaseReference; private TextInputEditText movieName; private TextInputEditText movieLogo; private RatingBar mRatingBar; private Button bSubmit; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.movie_fragment,container,false); movieName = (TextInputEditText) v.findViewById(R.id.tiet_movie_name); movieLogo = (TextInputEditText) v.findViewById(R.id.tiet_movie_logo); bSubmit = (Button) v.findViewById(R.id.b_submit); mRatingBar = (RatingBar) v.findViewById(R.id.rating_bar); //initializing database reference mDatabaseReference = FirebaseDatabase.getInstance().getReference(); bSubmit.setOnClickListener(this); return v; } @Override public void onClick(View view) { switch(view.getId()){ case R.id.b_submit: if(!isEmpty(movieName) && !isEmpty(movieName)){ myNewMovie("53", movieName.getText().toString().trim(),movieLogo.getText().toString(),mRatingBar.getRating()); }else{ if(isEmpty(movieName)){ Toast.makeText(getContext(), "Please enter a movie name!", Toast.LENGTH_SHORT).show(); }else if(isEmpty(movieLogo)){ Toast.makeText(getContext(), "Please specify a url for the logo", Toast.LENGTH_SHORT).show(); } } //to remove current fragment getActivity().onBackPressed(); break; } } private void myNewMovie(String userId, String movieName, String moviePoster, float rating) { //Creating a movie object with user defined variables Movie movie = new Movie(movieName,moviePoster,rating); //referring to movies node and setting the values from movie object to that location mDatabaseReference.child("users").child(userId).child("movies").push().setValue(movie); } //check if edittext is empty private boolean isEmpty(TextInputEditText textInputEditText) { if (textInputEditText.getText().toString().trim().length() > 0) return false; return true; } }
Next we declare a layout for this fragment. Here I’ve named it as movie_fragment.xml. and placed the following code inside it:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?android:attr/colorBackground" android:orientation="vertical" android:padding="5dp"> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/TextLabel"> <android.support.design.widget.TextInputEditText android:id="@+id/tiet_movie_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter A Movie Name" /> </android.support.design.widget.TextInputLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/tv_rating_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/rating_bar" android:layout_marginTop="15dp" android:text="Your Rating: " android:textSize="16sp" android:textStyle="italic"/> <RatingBar android:id="@+id/rating_bar" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/TextLabel"> <android.support.design.widget.TextInputEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Enter Movie Logo URL " android:id="@+id/tiet_movie_logo"/> </android.support.design.widget.TextInputLayout> <Button android:id="@+id/b_submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Submit"/> </LinearLayout>
Now if we run the project, if there are any movies previously entered in our Firebase Database, they will get loaded. If we click on Floating actionbar and add a movie with rating and url to the poster, and if we click on submit button, they will get stored in Firebase Database which will reflect across all the devices on which the app is running. In next article, we will discuss about Firebase Authentication.
[widget id=”text-15″]
Thank you for posing this tutorial.
First of all FireBaseUI version 0.4.3 will not work with FirebaseDatabase version 9.0.2, only with 9.2.1.
other than that you did a great job.
I wonder how complicate is to add Edit and delete from the device, since we need to store the push Id some how.
To delete from device you can use the following code: adapter.getRef(position).removeValue();
To edit from device you can use adapter.getItem(position).setMovieName() etc.
So, in short, you don’t need to store the push id.
Updated the code with latest FirebaseUI version of 0.4.4 and FirebaseDatabase Version of 9.4.0.
Cheers 🙂
Hi,
Could you please elaborate on “adapter.getRef(position).removeValue();”?
I’m still struggling to implement delete on swipe and edit details features to the list.
Thanks!
Why data save below in the json file. I want to save it in top position so that new data arrived first when i open my application.
The data will always save below in json file. However, You can reverse the Recyclerview layout by using the following line:
For StaggeredGridLayout: mLayoutManager.setReverseLayout(true);
Waooooh..Amaizing Tutorial…DOPE Coding
Hello, I been trying to get this code to function, the code as it is crashes when I use the
Picasso.with(MainActivity.this).load(model.getMoviePoster()).into(viewHolder.ivMoviePoster)
the code crashes when I use the “model.getMoviePoster()”. When I remove this portion of the code and actually add a link, “.load(“http://i.imgur.com/DvpvklR.png”)” The code runs, but I get the photo from the link I added. (ATTACHED)
So, when I try to upload a new url I keep getting the added links picture even though the url for the new photo I’m attempting to add is logging to the database.
I used the same code as listed above. Any suggestions on how to make it so every person can upload thier own individual photos?
11-11 05:54:46.696 13650-13650/? W/Zygote: mz_is_rooted false
11-11 05:54:46.699 13650-13650/? I/art: Late-enabling -Xcheck:jni
11-11 05:54:46.749 13650-13650/ln.uiimagefirebase I/InstantRun: Instant Run Runtime started. Android package is ln.uiimagefirebase, real application class is null.
11-11 05:54:46.815 13650-13650/ln.uiimagefirebase W/linker: /system/lib64/libfilterUtils.so: unused DT entry: type 0x6ffffffe arg 0x808
11-11 05:54:46.815 13650-13650/ln.uiimagefirebase W/linker: /system/lib64/libfilterUtils.so: unused DT entry: type 0x6fffffff arg 0x2
11-11 05:54:47.032 13650-13676/ln.uiimagefirebase W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-11 05:54:47.047 13650-13676/ln.uiimagefirebase W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-11 05:54:47.053 13650-13676/ln.uiimagefirebase W/ResourcesManager: Asset path ‘/system/framework/com.android.media.remotedisplay.jar’ does not exist or contains no resources.
11-11 05:54:47.053 13650-13676/ln.uiimagefirebase W/ResourcesManager: Asset path ‘/system/framework/com.android.location.provider.jar’ does not exist or contains no resources.
11-11 05:54:47.135 13650-13650/ln.uiimagefirebase I/FA: App measurement is starting up, version: 9877
11-11 05:54:47.135 13650-13650/ln.uiimagefirebase I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
11-11 05:54:47.142 13650-13650/ln.uiimagefirebase I/FA: To enable faster debug mode event logging run:
adb shell setprop firebase.analytics.debug-mode ln.uiimagefirebase
11-11 05:54:47.223 13650-13650/ln.uiimagefirebase I/FirebaseInitProvider: FirebaseApp initialization successful
11-11 05:54:47.453 13650-13650/ln.uiimagefirebase I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:4
11-11 05:54:47.453 13650-13650/ln.uiimagefirebase I/DynamiteModule: Selected remote version of com.google.android.gms.firebase_database, version >= 4
11-11 05:54:47.463 13650-13650/ln.uiimagefirebase E/System: stat file error, path is /data/data/com.google.android.gms/app_chimera/m/00000009/n/arm64-v8a, exception is android.system.ErrnoException: stat failed: ENOENT (No such file or directory)
11-11 05:54:47.541 13650-13688/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=firenotification-3382b.firebaseio.com; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:47.541 13650-13688/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
11-11 05:54:47.541 13650-13688/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=firenotification-3382b.firebaseio.com; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:47.541 13650-13688/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=1024; ai_family=0
11-11 05:54:47.544 13650-13688/ln.uiimagefirebase D/libc-netbsd: getaddrinfo: firenotification-3382b.firebaseio.com get result from proxy >>
11-11 05:54:47.544 13650-13688/ln.uiimagefirebase I/System.out: propertyValue:true
11-11 05:54:47.545 13650-13688/ln.uiimagefirebase I/System.out: [CDS]connect[firenotification-3382b.firebaseio.com/104.155.133.130:443] tm:90
11-11 05:54:47.585 13650-13650/ln.uiimagefirebase W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
11-11 05:54:48.142 13650-13695/ln.uiimagefirebase E/GED: Failed to get GED Log Buf, err(0)
11-11 05:54:48.142 13650-13695/ln.uiimagefirebase I/OpenGLRenderer: Initialized EGL, version 1.4
11-11 05:54:48.229 13650-13695/ln.uiimagefirebase W/MALI: glDrawArrays:714: [MALI] glDrawArrays takes more than 5ms here. Total elapse time(us): 7708
11-11 05:54:48.240 13650-13688/ln.uiimagefirebase E/NativeCrypto: ssl=0x7f6fc7fd00 cert_verify_callback x509_store_ctx=0x7f609d8128 arg=0x0
11-11 05:54:48.240 13650-13688/ln.uiimagefirebase E/NativeCrypto: ssl=0x7f6fc7fd00 cert_verify_callback calling verifyCertificateChain authMethod=DHE_RSA
11-11 05:54:48.591 13650-13688/ln.uiimagefirebase I/System.out: gba_cipher_suite:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
11-11 05:54:48.591 13650-13688/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=firenotification-3382b.firebaseio.com; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:48.591 13650-13688/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
11-11 05:54:49.221 13650-13688/ln.uiimagefirebase I/System.out: [CDS]close[41354]
11-11 05:54:49.221 13650-13688/ln.uiimagefirebase I/NetworkManagementSocketTagger: untagSocket(24)
11-11 05:54:49.232 13650-13720/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=s-usc1c-nss-105.firebaseio.com; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:49.232 13650-13720/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
11-11 05:54:49.232 13650-13720/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=s-usc1c-nss-105.firebaseio.com; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:49.232 13650-13720/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=1024; ai_family=0
11-11 05:54:49.236 13650-13720/ln.uiimagefirebase D/libc-netbsd: getaddrinfo: s-usc1c-nss-105.firebaseio.com get result from proxy >>
11-11 05:54:49.236 13650-13720/ln.uiimagefirebase I/System.out: propertyValue:true
11-11 05:54:49.236 13650-13720/ln.uiimagefirebase I/System.out: [CDS]connect[s-usc1c-nss-105.firebaseio.com/104.197.24.164:443] tm:90
11-11 05:54:50.479 13650-13650/ln.uiimagefirebase W/ResourceType: Too many attribute references, stopped at: 0x01010099
11-11 05:54:50.479 13650-13650/ln.uiimagefirebase W/ResourceType: Too many attribute references, stopped at: 0x0101009b
11-11 05:54:50.502 13650-13650/ln.uiimagefirebase W/ResourceType: Too many attribute references, stopped at: 0x01010099
11-11 05:54:50.502 13650-13650/ln.uiimagefirebase W/ResourceType: Too many attribute references, stopped at: 0x0101009b
11-11 05:54:50.833 13650-13720/ln.uiimagefirebase E/NativeCrypto: ssl=0x7f6fc7fd00 cert_verify_callback x509_store_ctx=0x7f609d81c8 arg=0x0
11-11 05:54:50.834 13650-13720/ln.uiimagefirebase E/NativeCrypto: ssl=0x7f6fc7fd00 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_RSA
11-11 05:54:51.430 13650-13720/ln.uiimagefirebase I/System.out: gba_cipher_suite:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
11-11 05:54:51.430 13650-13720/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=s-usc1c-nss-105.firebaseio.com; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:51.430 13650-13720/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
11-11 05:54:52.844 13650-13650/ln.uiimagefirebase W/SettingsInterface: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
11-11 05:54:52.875 13650-13650/ln.uiimagefirebase E/AndroidRuntime: FATAL EXCEPTION: main
Process: ln.uiimagefirebase, PID: 13650
java.lang.IllegalArgumentException: Path must not be empty.
at com.squareup.picasso.Picasso.load(Picasso.java:297)
at ln.uiimagefirebase.MainActivity$1.populateViewHolder(MainActivity.java:72)
at ln.uiimagefirebase.MainActivity$1.populateViewHolder(MainActivity.java:64)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:177)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6062)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6095)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5277)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5153)
at android.support.v7.widget.LayoutState.next(LayoutState.java:100)
at android.support.v7.widget.StaggeredGridLayoutManager.fill(StaggeredGridLayoutManager.java:1568)
at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:678)
at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:600)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3374)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3183)
at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1593)
at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:323)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:571)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5847)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1010)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
11-11 05:54:52.881 13650-13763/ln.uiimagefirebase I/System.out: url:https://www.google.co.in/search?q=hello&hl=en-US&source=lnms&prmd=mivn&tbm=isch&sa=X&ved=0ahUKEwjg9ozpzpzQAhVKpY8KHbJ-D5sQ_AUICCgC&biw=360&bih=567#imgrc=iomKndCSemKr5M%3A
11-11 05:54:52.881 13650-13763/ln.uiimagefirebase I/System.out: open:https://www.google.co.in/search?q=hello&hl=en-US&source=lnms&prmd=mivn&tbm=isch&sa=X&ved=0ahUKEwjg9ozpzpzQAhVKpY8KHbJ-D5sQ_AUICCgC&biw=360&bih=567#imgrc=iomKndCSemKr5M%3A
11-11 05:54:52.884 13650-13763/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=www.google.co.in; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:52.884 13650-13763/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
11-11 05:54:52.884 13650-13763/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: hostname=www.google.co.in; servname=(null); cache_mode=(null), netid=0; mark=0
11-11 05:54:52.884 13650-13763/ln.uiimagefirebase D/libc-netbsd: [getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=1024; ai_family=0
11-11 05:54:52.908 13650-13650/ln.uiimagefirebase I/Process: Sending signal. PID: 13650 SIG: 9
the url you are passing to picasso at line 297 is empty. Make sure that you pass a non-empty url.
plz solve my error
Hi,
i tried your code and it works just perfectly.but now what is blocking is the onClickListener. I searched all over internet and tried all possible solutions but click on items(and then know the id of movie clicked for example) doesn’t work. So please can you help me to add this clickListener to the mRecyclerView?
Thanks,
and very good job 😉
@Override
protected void populateViewHolder(PubViewHolder viewHolder, final Pub pub, final int position) {
viewHolder.name.setText(pub.getName());
viewHolder.address.setText(pub.getAddress());
viewHolder.map.setText(pub.getMap());
Glide.with(ContentFragment_GeneralMain.this)
.load(pub.getCover())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.problems)
.into(viewHolder.cover);
viewHolder.cover.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),”Click: ” + pub.getName() + ” ” + pub.getAddress() + ” ” + position, Toast.LENGTH_SHORT).show();
}
});
}
Hello. I implemented the full code over the last 2 days and I have never been able to actually see anything returned from the database json file. I rebuilt it several times on my own app and then had to delete everything and install exactly as is written here. I can add to the database, but there is nothing on the main page except the title, the text view stating there are no movies, and the add movie button. Is there something I am missing, or that is not included with the code here? I even downloaded from git and combed line by line to make sure everything matched. I need to be able to display the entered information in my application. The app doesn’t crash or anything. It just doesn’t show the cards in the recyclerview.
I got it fixed.I think I was handling the child setting wrong. Works great now.
pls share the source code
Hi sir! How i can implement search filters with this code?
whats the code for
swipe to delete the card and respective delete data from firebase
Hi,
Can u please help me out in Setting an OnClickListener on the RecyclerView list so that when a when a list is clicked it should call an Intent