Skip to content

Commit ed84bac

Browse files
committed
More codelab changes
1 parent 53e9f2d commit ed84bac

File tree

10 files changed

+48
-117
lines changed

10 files changed

+48
-117
lines changed

codelabs/chat/README.md

Lines changed: 48 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -372,156 +372,87 @@ As a final step, we're going to allow the users of our app to log in using email
372372

373373
![main_activity.xml with login button](images/6_2.png)
374374

375-
3. Now create a new layout called dialog_signin.xml
375+
3. Extend FirebaseLoginBaseActivity
376376

377-
![Menu option to add a new layout xml](images/6_3.png)
377+
Although extending `ListActivity` was useful earlier, when it saved some lines of code, it's now more important that we extend `FirebaseLoginBaseActivity`.
378378

379-
4. In this dialog_signin.xml, we'll model the body of the sign-in dialog
380-
381-
```xml
382-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
383-
android:orientation="vertical"
384-
android:layout_width="wrap_content"
385-
android:layout_height="wrap_content">
386-
<EditText
387-
android:id="@+id/email"
388-
android:inputType="textEmailAddress"
389-
android:layout_width="match_parent"
390-
android:layout_height="wrap_content"
391-
android:layout_marginTop="16dp"
392-
android:layout_marginLeft="4dp"
393-
android:layout_marginRight="4dp"
394-
android:layout_marginBottom="4dp"
395-
android:hint="Email" />
396-
<EditText
397-
android:id="@+id/password"
398-
android:inputType="textPassword"
399-
android:layout_width="match_parent"
400-
android:layout_height="wrap_content"
401-
android:layout_marginTop="4dp"
402-
android:layout_marginLeft="4dp"
403-
android:layout_marginRight="4dp"
404-
android:layout_marginBottom="16dp"
405-
android:hint="Password"/>
406-
</LinearLayout>
407-
```
408-
409-
We have two `EditText controls` under each other, one for the user's name, the other for their password.
410-
The rest of the popup will be handled by a stock Android dialog.
411-
412-
![dialog_signin.xml](images/6_4.png)
413-
414-
4. Since our app will display the sign-in dialog as a popup, add the handling to MainActivity.java:
379+
We'll change our `MainActivity` definition to extend `FirebaseLoginBaseActivity`.
415380

416381
```java
417-
Button loginButton = (Button) findViewById(R.id.login);
418-
loginButton.setOnClickListener(new View.OnClickListener() {
419-
@Override
420-
public void onClick(View v) {
421-
new AlertDialog.Builder(MainActivity.this)
422-
.setMessage("Enter your email address and password")
423-
.setTitle("Log in")
424-
.setView(MainActivity.this.getLayoutInflater().inflate(R.layout.dialog_signin, null))
425-
.setNegativeButton("Cancel", null)
426-
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
427-
public void onClick(DialogInterface dialog, int id) {
428-
AlertDialog dlg = (AlertDialog) dialog;
429-
final String email = ((TextView)dlg.findViewById(R.id.email)).getText().toString();
430-
final String password =((TextView)dlg.findViewById(R.id.password)).getText().toString();
431-
432-
// TODO: sign in to Firebase
433-
}
434-
})
435-
.create()
436-
.show();
437-
}
438-
});
382+
public class MainActivity extends FirebaseLoginBaseActivity {
439383
```
440384

441-
This method builds and show the dialog, with our two text boxes as the main body.
442-
443-
![Login dialog](images/6_5.png)
444-
445-
When the user clicks OK, it extracts the email address and password from the text controls.
446-
447-
![login OnClickHandler code](images/6_6.png)
448-
449-
5. Now wire the values that we got from the dialog to the Firebase Authentication back-end. Replace the `TODO` with the following code:
385+
Then we need to update our usage of FirebaseListAdapter.
450386

451387
```java
452-
mFirebaseRef.createUser(email, password, new Firebase.ResultHandler() {
453-
@Override
454-
public void onSuccess() {
455-
mFirebaseRef.authWithPassword(email, password, null);
456-
}
388+
final ListView listView = (ListView) this.findViewById(android.R.id.list);
389+
390+
mListAdapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class,
391+
android.R.layout.two_line_list_item, mFirebaseRef) {
457392
@Override
458-
public void onError(FirebaseError firebaseError) {
459-
mFirebaseRef.authWithPassword(email, password, null);
393+
protected void populateView(View v, ChatMessage model, int position) {
394+
((TextView)v.findViewById(android.R.id.text1)).setText(model.getName());
395+
((TextView)v.findViewById(android.R.id.text2)).setText(model.getText());
460396
}
461-
});
397+
};
398+
listView.setAdapter(mListAdapter);
462399
```
463400

464-
In this code, we always try to register the user. If the user already registered that will result in `onError`, otherwise it will result on onSuccess.
401+
![Update FirebaseListAdapter code](images/6_3.png)
465402

466-
Either way, we next call `authWithPassword` to authenticate the (pre-existing or just-created) user.
467-
468-
![OnClickHandler with the login behavior](images/6_7.png)
469-
470-
6. With the above we have the registration/login flow working. But we still need to listen to when Firebase Authentication tells us the user has been authenticated, so that we can store the username and use that in the chat message instead of the hard-coded value we have now.
471-
472-
Add a field to the class to hold the user name:
403+
Finally we need to add a few event handlers onto `MainActivity` so we can react to login events.
473404

474405
```java
475-
String mUsername;
476-
```
406+
@Override
407+
protected Firebase getFirebaseRef() {
408+
return mFirebaseRef;
409+
}
477410

478-
Add the end of the `onCreate` method, add a callback method that listens for authentication state changes in Firebase:
411+
@Override
412+
protected void onFirebaseLoginProviderError(FirebaseLoginError firebaseLoginError) {
479413

480-
```java
481-
mFirebaseRef.addAuthStateListener(new Firebase.AuthStateListener() {
482-
@Override
483-
public void onAuthStateChanged(AuthData authData) {
484-
if(authData != null) {
485-
mUsername = ((String)authData.getProviderData().get("email"));
486-
findViewById(R.id.login).setVisibility(View.INVISIBLE);
487-
}
488-
else {
489-
mUsername = null;
490-
findViewById(R.id.login).setVisibility(View.VISIBLE);
491-
}
492-
}
493-
});
494-
```
414+
}
495415

496-
Firebase calls our listener whenever the authentication state changes, so whenever the user logs in or out. When the user logs in, we store their email address in our field and hide the login button.
416+
@Override
417+
protected void onFirebaseLoginUserError(FirebaseLoginError firebaseLoginError) {
497418

498-
![AuthStateListener](images/6_8.png)
419+
}
420+
```
499421

500-
Firebase Authentication supports multiple authentication providers and each of them exposes a different set of data. For example, if we'd allow our users to authenticate with their existing Twitter account, we could identify them by their twitter handle.
422+
![Add Firebase event handlers](images/6_3.5.png)
501423

502-
7. Finally, replace the hard-coded username with the field we just populated:
424+
4. Enable Password Authentication
503425

504426
```java
505-
mFirebaseRef.push().setValue(new ChatMessage(MainActivity.this.mUsername, text));
427+
@Override
428+
protected void onStart() {
429+
super.onStart();
430+
setEnabledAuthProvider(AuthProviderType.PASSWORD);
431+
}
506432
```
507433

508-
![messages with one from [email protected]](images/6_9.png)
509-
510-
We could definitely improve the layout of things. But this step has been long enough as it is. So let's wrap up with a few notes.
434+
![Enable PASSWORD auth](images/6_4.png)
511435

512-
8. One thing you may note is that the user stays logged in, even when they restart the app. If instead you want to sign out the user, you can call:
436+
5. Wire up login button
513437

514438
```java
515-
mFirebaseRef.unauth();
439+
Button loginButton = (Button) this.findViewById(R.id.login_button);
440+
441+
loginButton.setOnClickListener(new View.OnClickListener() {
442+
@Override
443+
public void onClick(View v) {
444+
showFirebaseLoginPrompt();
445+
}
446+
});
516447
```
517448

518-
This will trigger the `AuthStateListener` we created before, which will clear the username field and re-enable the login button.
449+
![Enable PASSWORD auth](images/6_5.png)
519450

520-
9. If you want to know which users logged in to your application, you can find them in the Login & Auth tab of your Firebase's dashboard.
451+
If you want to know which users logged in to your application, you can find them in the Login & Auth tab of your Firebase's dashboard.
521452
522-
![Auth dashboard with some users](images/6_10.png)
453+
![Auth dashboard with some users](images/6_10.png)
523454
524-
This is also where you can configure the password reset emails that you can send to your users, in case they forgot their password.
455+
This is also where you can configure the password reset emails that you can send to your users, in case they forgot their password.
525456
526457
## Wrap-up
527458

codelabs/chat/images/6_2.png

-124 KB
Loading

codelabs/chat/images/6_3.5.png

125 KB
Loading

codelabs/chat/images/6_3.png

-196 KB
Loading

codelabs/chat/images/6_4.png

-103 KB
Loading

codelabs/chat/images/6_5.png

65.5 KB
Loading

codelabs/chat/images/6_6.png

-263 KB
Binary file not shown.

codelabs/chat/images/6_7.png

-257 KB
Binary file not shown.

codelabs/chat/images/6_8.png

-245 KB
Binary file not shown.

codelabs/chat/images/6_9.png

-75.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)