android-lecture

android lecture notes

View on GitHub

layout: true .top-line[]


class: center, middle

모바일 백앤드서비스(Firebase)


모바일 백앤드 서비스


Firebase 기능(개발->성장->수익)


Firebase 시작하기


Firebase 시작하기


Firebase 시작하기


Firebase 시작하기


Firebase Authentication


Authentication

private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

*   mAuth = FirebaseAuth.getInstance();   // 인증 객체 가져오기

*   mAuthListener = new FirebaseAuth.AuthStateListener() {  // 인증 상태 리스너
        @Override
*       public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
            } else {
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
        }
    };
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/LoginActivity.java#L40-L58]


Authentication

@Override
public void onStart() {
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/LoginActivity.java#L84-L96]


Authentication

public void onButtonLogin(View v) {
    String email = ((EditText)findViewById(R.id.etEmail)).getText().toString();
    String password = ((EditText)findViewById(R.id.etPassword)).getText().toString();
*   mAuth.signInWithEmailAndPassword(email, password)  // Task 객체 리턴
*       .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
*           public void onComplete(@NonNull Task<AuthResult> task) {
                Log.d(TAG, "signInWithEmail:onComplete:" + task.isSuccessful());
*               if (!task.isSuccessful()) { // 로그인 실패
                    Log.w(TAG, "signInWithEmail", task.getException());
                    Toast.makeText(LoginActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                }
            }
        });
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/LoginActivity.java#L61-L82]


Authentication

    FirebaseAuth.getInstance().signOut();

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MainActivity.java#L115-L118]


Authentication

<img src=”images/firebaseconsoleauth.png” width=90%>


Authentication

<img src=”images/firebaseconsoleauth2.png” width=90%>


Storage


Storage


Storage


Storage

private FirebaseStorage mFirebaseStorage;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mAuth = FirebaseAuth.getInstance();
    FirebaseUser user = mAuth.getCurrentUser();

*   if (user == null)  // 인증이 정상적으로 된 사용자만…
        finish();

*   mFirebaseStorage = FirebaseStorage.getInstance();

    ...생략...
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MainActivity.java#L36-L44]


Storage

private void displayImage() {
*   StorageReference storageRef = mFirebaseStorage.getReferenceFromUrl("gs://myfirebase-332e8.appspot.com/3.jpg");
*   storageRef.getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
        @Override
        public void onSuccess(byte[] bytes) {
            Log.d(TAG, "getBytes Success");
            // Use the bytes to display the image
            Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            ImageView iv = (ImageView)findViewById(R.id.imageView);
            iv.setImageBitmap(bmp);
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Log.d(TAG, "getBytes Failed");
        }
    });
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MainActivity.java#L62-L81]


Storage

<img src=”images/firebaseconsolestorage.png” width=70%>


Storage

<img src=”images/firebaseconsolestoragerule.png” width=90%>


Remote Config


Remote Config

private FirebaseRemoteConfig mFirebaseRemoteConfig;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();

    FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
*           .setDeveloperModeEnabled(BuildConfig.DEBUG)  // 개발자 모드로.
            .build();
    mFirebaseRemoteConfig.setConfigSettings(configSettings);
    mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);

    displayConfig();
}

private void displayConfig() {
    Boolean cheat_enabled = mFirebaseRemoteConfig.getBoolean("cheat_enabled");
    ((TextView)findViewById(R.id.textView_cheat)).setText("cheat_enabled=" + cheat_enabled);
    long price = mFirebaseRemoteConfig.getLong("your_price");
    ((TextView)findViewById(R.id.textView_price)).setText("your_price is " + price);
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MainActivity.java#L45-L58]


Remote Config


Remote Config

<?xml version="1.0" encoding="utf-8"?>
<defaultsMap xmlns:android="http://schemas.android.com/apk/res/android">
    <entry>
        <key>your_price</key>
        <value>100</value>
    </entry>
    <entry>
        <key>cheat_enabled</key>
        <value>false</value>
    </entry>
</defaultsMap>

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/res/xml/remote_config_defaults.xml]


Remote Config

public void onFetchButton(View v) {
    long cacheExpiration = 3600; // 1 hour in seconds.
*   // 개발자 모드에서는 cacheExpiration을 0으로 해서 매번 서버로부터 가져오게 함.
*   // 개발자 모드가 아니면 자주 RemoteConfig를 가져올 수 없음.
    if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
        cacheExpiration = 0;
    }

*   mFirebaseRemoteConfig.fetch(cacheExpiration)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Fetch Succeeded");
                        // Once the config is successfully fetched it must be activated
                        //  before newly fetched values are returned.
*                       mFirebaseRemoteConfig.activateFetched();
                    } else {
                        Log.d(TAG, "Fetch failed");
                    }
                    displayConfig();
                }
            });
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MainActivity.java#L90-L113]


Remote Config

<img src=”images/firebaseconsolerc.png” width=90%>


Notification


Notification

<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/AndroidManifest.xml#L19-L23]


Notification

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            msgBody = remoteMessage.getNotification().getBody();
            Log.d(TAG, "Message Notification Body: " + msgBody);
        }
    }

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MyFirebaseMessagingService.java#L12-L35]


Notification


Notification (앱에서 알림 받기)


Cloud Messaging


Cloud Messaging

<img src=”https://i.imgur.com/9XzwPqc.png” width=80%>

.footnote[출처: https://guides.codepath.com/android/Google-Cloud-Messaging]


Cloud Messaging

 1. Firebase 서버에 접속하여 토큰을 받음

<img src=”http://imgur.com/5UPxP3n.png” width=80%>

.footnote[출처: https://guides.codepath.com/android/Google-Cloud-Messaging]


Cloud Messaging

 2. 받은 토큰을 가지고 3rd party 서버에 접속

<img src=”http://imgur.com/ItRPQ7N.png” width=80%>

.footnote[출처: https://guides.codepath.com/android/Google-Cloud-Messaging]


Cloud Messaging

 3. 3rd party 서버가 Firebase 서버를 통해 앱으로 푸시 알림 보냄

<img src=”http://imgur.com/adiFo8w.png” width=80%>

.footnote[출처: https://guides.codepath.com/android/Google-Cloud-Messaging]


Cloud Messaging (안드로이드 앱)


Cloud Messaging (안드로이드 앱)

<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

<service
    android:name=".MyFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
    </intent-filter>
</service>

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/AndroidManifest.xml#L24-L28]


Cloud Messaging (안드로이드 앱)

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
    private static final String TAG = "MyFirebaseIIDService";

    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        // sendRegistrationToServer(refreshedToken);
    }
}

.footnote[https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/LoginActivity.java#L37-L38 https://github.com/jyheo/AndroidTutorial/blob/master/FirebaseTest/app/src/main/java/com/example/jyheo/firebasetest/MyFirebaseInstanceIDService.java#L12-L24]


Cloud Messaging (3rd Party 서버)


Cloud Messaging (3rd Party 서버)

curl –header “Authorization: key=AIzaSyC3-Rz5MiJmWxBy78io0SG4HYHwPJbTsL0” –header Content-Type:”application/json” https://fcm.googleapis.com/fcm/send -d “{ "notification": { "title": \“title here", "text": \“message body here" }, "to" : "edGuBDxqN4o:APA91bG3pEr0EOIZcSskSvPviMm0yzvulS-DehnaN16wGeGqoMCbt-ZLgZn26fe0S4PVKluJOZDVkYsZecA_VeDvT0Fe-6XI8MZsM5FqN3XJX6o_LnSmAbXt3JwVGCiYuWP9ioyTk8lO"}”