Skip to content

Commit 96af06c

Browse files
committed
Merge pull request #25 from firebase/abe-0.3.0
Various Login fixes and Dialog
2 parents ff00df8 + 960a7af commit 96af06c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1339
-295
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
.DS_Store
55
/build
66
/captures
7-
/library/target
7+
/library/target
8+
/**/*.iml

README.md

Lines changed: 138 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,28 @@ So say we have these chat messages in our Firebase database:
4040

4141
We can represent a chat message with this Java class:
4242

43-
public class ChatMessage {
44-
String message;
45-
String name;
43+
```java
44+
public class ChatMessage {
45+
String message;
46+
String name;
4647

47-
public ChatMessage() {
48-
}
49-
50-
public ChatMessage(String name, String message) {
51-
this.message = message;
52-
this.name = name;
53-
}
48+
public ChatMessage() {
49+
}
5450

55-
public String getMessage() {
56-
return message;
57-
}
51+
public ChatMessage(String name, String message) {
52+
this.message = message;
53+
this.name = name;
54+
}
5855

59-
public String getName() {
60-
return name;
61-
}
56+
public String getMessage() {
57+
return message;
6258
}
6359

60+
public String getName() {
61+
return name;
62+
}
63+
}
64+
```
6465
A few things to note here:
6566

6667
* the field have the exact same name as the properties in Firebase. This allows Firebase to automatically map the properties to these fields.
@@ -70,28 +71,30 @@ A few things to note here:
7071

7172
A little-known feature of Firebase for Android is that you can pass an instance of this `ChatMessage` class to `setValue()`:
7273

73-
Firebase ref = new Firebase("https://nanochat.firebaseio.com/");
74-
ChatMessage msg = new ChatMessage("puf", "Hello FirebaseUI world!");
75-
ref.push().setValue(msg);
76-
74+
```java
75+
Firebase ref = new Firebase("https://nanochat.firebaseio.com/");
76+
ChatMessage msg = new ChatMessage("puf", "Hello FirebaseUI world!");
77+
ref.push().setValue(msg);
78+
```
7779
The Firebase Android client will read the values from the `msg` and write them into the properties of the new child in the database.
7880

7981
Conversely, we can read a `ChatMessage` straight from a `DataSnapshot` in our event handlers:
8082

81-
ref.limitToLast(5).addValueEventListener(new ValueEventListener() {
82-
@Override
83-
public void onDataChange(DataSnapshot snapshot) {
84-
for (DataSnapshot msgSnapshot: snapshot.getChildren()) {
85-
ChatMessage msg = msgSnapshot.getValue(ChatMessage.class);
86-
Log.i("Chat", chat.getName()+": "+chat.getMessage());
87-
}
88-
}
89-
@Override
90-
public void onCancelled(FirebaseError firebaseError) {
91-
Log.e("Chat", "The read failed: " + firebaseError.getMessage());
83+
```java
84+
ref.limitToLast(5).addValueEventListener(new ValueEventListener() {
85+
@Override
86+
public void onDataChange(DataSnapshot snapshot) {
87+
for (DataSnapshot msgSnapshot: snapshot.getChildren()) {
88+
ChatMessage msg = msgSnapshot.getValue(ChatMessage.class);
89+
Log.i("Chat", chat.getName()+": "+chat.getMessage());
9290
}
93-
});
94-
91+
}
92+
@Override
93+
public void onCancelled(FirebaseError firebaseError) {
94+
Log.e("Chat", "The read failed: " + firebaseError.getMessage());
95+
}
96+
});
97+
```
9598
In the above snippet we have a query for the last 5 chat messages. Whenever those change (i.e. when an new message is added)
9699
we get the `ChatMessage` objects from the `DataSnapshot` with `getValue(ChatMessage.class)`. The Firebase Android client will
97100
then read the properties that it got from the database and map them to the fields of our `ChatMessage` class.
@@ -105,53 +108,59 @@ But when we build our app using FirebaseUI, we often won't need to register our
105108

106109
We'll assume you've already added a `ListView` to your layout and have looked it up in the `onCreate` method of your activity:
107110

108-
@Override
109-
protected void onCreate(Bundle savedInstanceState) {
110-
super.onCreate(savedInstanceState);
111-
setContentView(R.layout.activity_main);
111+
```java
112+
@Override
113+
protected void onCreate(Bundle savedInstanceState) {
114+
super.onCreate(savedInstanceState);
115+
setContentView(R.layout.activity_main);
112116

113-
ListView messagesView = (ListView) findViewById(R.id.messages_list);
114-
}
117+
ListView messagesView = (ListView) findViewById(R.id.messages_list);
118+
}
119+
```
115120

116121
#### Set up connection to Firebase
117122

118123
First we'll tell Firebase that we intend to use it in this activity and set up a reference to the database of chat message.
119124

120-
@Override
121-
protected void onCreate(Bundle savedInstanceState) {
122-
super.onCreate(savedInstanceState);
123-
setContentView(R.layout.activity_main);
125+
```java
126+
@Override
127+
protected void onCreate(Bundle savedInstanceState) {
128+
super.onCreate(savedInstanceState);
129+
setContentView(R.layout.activity_main);
124130

125-
ListView messagesView = (ListView) findViewById(R.id.messages_list);
131+
ListView messagesView = (ListView) findViewById(R.id.messages_list);
126132

127-
Firebase.setAndroidContext(this);
128-
Firebase ref = new Firebase("https://nanochat.firebaseio.com");
129-
}
133+
Firebase.setAndroidContext(this);
134+
Firebase ref = new Firebase("https://nanochat.firebaseio.com");
135+
}
136+
```
130137

131138
#### Create custom FirebaseListAdapter subclass
132139

133140
Next, we need to create a subclass of the `FirebaseListAdapter` with the correct parameters and implement its `populateView` method:
134141

135-
@Override
136-
protected void onCreate(Bundle savedInstanceState) {
137-
super.onCreate(savedInstanceState);
138-
setContentView(R.layout.activity_main);
142+
```java
143+
@Override
144+
protected void onCreate(Bundle savedInstanceState) {
145+
super.onCreate(savedInstanceState);
146+
setContentView(R.layout.activity_main);
139147

140-
ListView messagesView = (ListView) findViewById(R.id.messages_list);
148+
ListView messagesView = (ListView) findViewById(R.id.messages_list);
141149

142-
Firebase.setAndroidContext(this);
143-
Firebase ref = new Firebase("https://nanochat.firebaseio.com");
150+
Firebase.setAndroidContext(this);
151+
Firebase ref = new Firebase("https://nanochat.firebaseio.com");
144152

145-
mAdapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class, android.R.layout.two_line_list_item, ref) {
146-
@Override
147-
protected void populateView(View view, ChatMessage chatMessage) {
148-
((TextView)view.findViewById(android.R.id.text1)).setText(chatMessage.getName());
149-
((TextView)view.findViewById(android.R.id.text2)).setText(chatMessage.getMessage());
153+
mAdapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class, android.R.layout.two_line_list_item, ref) {
154+
@Override
155+
protected void populateView(View view, ChatMessage chatMessage) {
156+
((TextView)view.findViewById(android.R.id.text1)).setText(chatMessage.getName());
157+
((TextView)view.findViewById(android.R.id.text2)).setText(chatMessage.getMessage());
150158

151-
}
152-
};
153-
messagesView.setListAdapter(mAdapter);
154-
}
159+
}
160+
};
161+
messagesView.setListAdapter(mAdapter);
162+
}
163+
```
155164

156165
In this last snippet we create a subclass of `FirebaseListAdapter`.
157166
We tell is that it is of type `<ChatMessage>`, so that it is a type-safe collection. We also tell it to use
@@ -171,51 +180,55 @@ correct `TextView` controls from the `view`. The code is a bit verbose, but hey.
171180
Finally, we need to clean up after ourselves. When the activity is destroyed, we need to call `release()`
172181
on the `ListAdapter` so that it can stop listening for changes in the Firebase database.
173182

174-
@Override
175-
protected void onDestroy() {
176-
super.onDestroy();
177-
mAdapter.cleanup();
178-
}
183+
```java
184+
@Override
185+
protected void onDestroy() {
186+
super.onDestroy();
187+
mAdapter.cleanup();
188+
}
189+
```
179190

180191
#### Sending chat messages
181192

182193
Remember when we showed how to use the `ChatMessage` class in `setValue()`.
183194
We can now use that in our activity to allow sending a message:
184195

185-
@Override
186-
protected void onCreate(Bundle savedInstanceState) {
187-
super.onCreate(savedInstanceState);
188-
setContentView(R.layout.activity_main);
189-
190-
ListView messagesView = (ListView) findViewById(R.id.messages_list);
191-
192-
Firebase.setAndroidContext(this);
193-
Firebase ref = new Firebase("https://nanochat.firebaseio.com");
194-
195-
mAdapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class, android.R.layout.two_line_list_item, ref) {
196-
@Override
197-
protected void populateView(View view, ChatMessage chatMessage) {
198-
((TextView)view.findViewById(android.R.id.text1)).setText(chatMessage.getName());
199-
((TextView)view.findViewById(android.R.id.text2)).setText(chatMessage.getMessage());
200-
}
201-
};
202-
setListAdapter(mAdapter);
203-
204-
final EditText mMessage = (EditText) findViewById(R.id.message_text);
205-
findViewById(R.id.send_button).setOnClickListener(new View.OnClickListener() {
206-
@Override
207-
public void onClick(View v) {
208-
mRef.push().setValue(new ChatMessage("puf", mMessage.getText().toString()));
209-
mMessage.setText("");
210-
}
211-
});
212-
}
196+
```java
197+
@Override
198+
protected void onCreate(Bundle savedInstanceState) {
199+
super.onCreate(savedInstanceState);
200+
setContentView(R.layout.activity_main);
213201

214-
@Override
215-
protected void onDestroy() {
216-
super.onDestroy();
217-
mAdapter.cleanup();
218-
}
202+
ListView messagesView = (ListView) findViewById(R.id.messages_list);
203+
204+
Firebase.setAndroidContext(this);
205+
Firebase ref = new Firebase("https://nanochat.firebaseio.com");
206+
207+
mAdapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class, android.R.layout.two_line_list_item, ref) {
208+
@Override
209+
protected void populateView(View view, ChatMessage chatMessage) {
210+
((TextView)view.findViewById(android.R.id.text1)).setText(chatMessage.getName());
211+
((TextView)view.findViewById(android.R.id.text2)).setText(chatMessage.getMessage());
212+
}
213+
};
214+
setListAdapter(mAdapter);
215+
216+
final EditText mMessage = (EditText) findViewById(R.id.message_text);
217+
findViewById(R.id.send_button).setOnClickListener(new View.OnClickListener() {
218+
@Override
219+
public void onClick(View v) {
220+
mRef.push().setValue(new ChatMessage("puf", mMessage.getText().toString()));
221+
mMessage.setText("");
222+
}
223+
});
224+
}
225+
226+
@Override
227+
protected void onDestroy() {
228+
super.onDestroy();
229+
mAdapter.cleanup();
230+
}
231+
```
219232

220233
Et voila: a minimal, yet fully functional, chat app in about 30 lines of code. Not bad, right?
221234

@@ -235,35 +248,39 @@ A ViewHolder is similar to container of a ViewGroup that allows simple lookup of
235248
If we use the same layout as before (`android.R.layout.two_line_list_item`), there are two `TextView`s in there.
236249
We can wrap that in a ViewHolder with:
237250

238-
private static class ChatMessageViewHolder extends RecyclerView.ViewHolder {
239-
TextView messageText;
240-
TextView nameText;
251+
```java
252+
private static class ChatMessageViewHolder extends RecyclerView.ViewHolder {
253+
TextView messageText;
254+
TextView nameText;
241255

242-
public ChatMessageViewHolder(View itemView) {
243-
super(itemView);
244-
nameText = (TextView)itemView.findViewById(android.R.id.text1);
245-
messageText = (TextView) itemView.findViewById(android.R.id.text2);
246-
}
256+
public ChatMessageViewHolder(View itemView) {
257+
super(itemView);
258+
nameText = (TextView)itemView.findViewById(android.R.id.text1);
259+
messageText = (TextView) itemView.findViewById(android.R.id.text2);
247260
}
261+
}
262+
```
248263

249264
There's nothing magical going on here; we're just mapping numeric IDs and casts into a nice, type-safe contract.
250265

251266
### Create a custom FirebaseListAdapter
252267

253268
Just like we did for FirebaseListAdapter, we'll create an anonymous subclass for our ChatMessages:
254269

255-
RecyclerView recycler = (RecyclerView) findViewById(R.id.messages_recycler);
256-
recycler.setHasFixedSize(true);
257-
recycler.setLayoutManager(new LinearLayoutManager(this));
258-
259-
mAdapter = new FirebaseRecyclerViewAdapter<ChatMessage, ChatMessageViewHolder>(ChatMessage.class, android.R.layout.two_line_list_item, ChatMessageViewHolder.class, mRef) {
260-
@Override
261-
public void populateViewHolder(ChatMessageViewHolder chatMessageViewHolder, ChatMessage chatMessage) {
262-
chatMessageViewHolder.nameText.setText(chatMessage.getName());
263-
chatMessageViewHolder.messageText.setText(chatMessage.getMessage());
264-
}
265-
};
266-
recycler.setAdapter(mAdapter);
270+
```java
271+
RecyclerView recycler = (RecyclerView) findViewById(R.id.messages_recycler);
272+
recycler.setHasFixedSize(true);
273+
recycler.setLayoutManager(new LinearLayoutManager(this));
274+
275+
mAdapter = new FirebaseRecyclerViewAdapter<ChatMessage, ChatMessageViewHolder>(ChatMessage.class, android.R.layout.two_line_list_item, ChatMessageViewHolder.class, mRef) {
276+
@Override
277+
public void populateViewHolder(ChatMessageViewHolder chatMessageViewHolder, ChatMessage chatMessage) {
278+
chatMessageViewHolder.nameText.setText(chatMessage.getName());
279+
chatMessageViewHolder.messageText.setText(chatMessage.getMessage());
280+
}
281+
};
282+
recycler.setAdapter(mAdapter);
283+
```
267284

268285
Like before, we get a custom RecyclerView populated with data from Firebase by setting the properties to the correct fields.
269286

app/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ android {
77

88
defaultConfig {
99
applicationId "com.firebase.uidemo"
10-
minSdkVersion 10
10+
minSdkVersion 15
1111
targetSdkVersion 22
1212
versionCode 1
1313
versionName "1.0"
@@ -33,5 +33,6 @@ dependencies {
3333
compile 'com.google.android.gms:play-services-plus:8.1.0'
3434
compile 'com.firebase:firebase-client-android:2.3.1'
3535
compile 'com.android.support:recyclerview-v7:22.2.1'
36+
compile 'com.facebook.android:facebook-android-sdk:4.6.0'
3637
compile project(':library')
3738
}

app/src/main/AndroidManifest.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,27 @@
2020
<category android:name="android.intent.category.LAUNCHER" />
2121
</intent-filter>
2222
</activity>
23+
24+
<!-- Twitter Configuration -->
25+
<activity android:name="com.firebase.ui.auth.TwitterPromptActivity" />
26+
<meta-data
27+
android:name="com.firebase.ui.TwitterKey"
28+
android:value="@string/twitter_app_key"/>
29+
<meta-data
30+
android:name="com.firebase.ui.TwitterSecret"
31+
android:value="@string/twitter_app_secret"/>
32+
33+
<!-- Facebook Configuration -->
34+
<activity
35+
android:name="com.facebook.FacebookActivity"
36+
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
37+
android:label="@string/app_name"
38+
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
39+
<meta-data
40+
android:name="com.facebook.sdk.ApplicationId"
41+
android:value="@string/facebook_app_id" />
42+
43+
2344
</application>
2445

2546
</manifest>

app/src/main/ic_google-web.png

5.23 KB
Loading

0 commit comments

Comments
 (0)