| @@ -0,0 +1,337 @@ | ||
| package com.example.hunter.planstart.GoogleSignIn; | ||
|
|
||
| import android.app.ProgressDialog; | ||
| import android.content.Intent; | ||
| import android.os.Bundle; | ||
| import android.support.v7.app.AppCompatActivity; | ||
| import android.util.Log; | ||
| import android.view.View; | ||
| import android.widget.Button; | ||
| import android.widget.EditText; | ||
| import android.widget.Toast; | ||
|
|
||
| import com.example.hunter.planstart.MainActivity; | ||
| import com.example.hunter.planstart.R; | ||
| import com.google.android.gms.auth.api.Auth; | ||
| import com.google.android.gms.auth.api.signin.GoogleSignInAccount; | ||
| import com.google.android.gms.auth.api.signin.GoogleSignInOptions; | ||
| import com.google.android.gms.auth.api.signin.GoogleSignInResult; | ||
| import com.google.android.gms.common.ConnectionResult; | ||
| import com.google.android.gms.common.SignInButton; | ||
| import com.google.android.gms.common.api.GoogleApiClient; | ||
| import com.google.android.gms.common.api.OptionalPendingResult; | ||
| import com.google.android.gms.common.api.ResultCallback; | ||
| import com.google.android.gms.common.api.Status; | ||
|
|
||
| import butterknife.Bind; | ||
| import butterknife.ButterKnife; | ||
|
|
||
| public class googleSignActivity extends AppCompatActivity implements | ||
| GoogleApiClient.OnConnectionFailedListener, | ||
| View.OnClickListener { | ||
|
|
||
| private static final String TAG = "SignInActivity"; | ||
| private static final int REQUEST_SIGNUP = 0; | ||
|
|
||
| @Bind(R.id.input_email) | ||
| EditText _emailText; | ||
| @Bind(R.id.input_password) EditText _passwordText; | ||
| @Bind(R.id.btn_login) | ||
| Button _loginButton; | ||
|
|
||
|
|
||
| private static final int RC_SIGN_IN = 9001; | ||
| private GoogleApiClient mGoogleApiClient; | ||
| // private TextView mStatusTextView; | ||
| private ProgressDialog mProgressDialog; | ||
|
|
||
| @Override | ||
| protected void onCreate(Bundle savedInstanceState) { | ||
| super.onCreate(savedInstanceState); | ||
| setContentView(R.layout.activity_google_sign); | ||
| //LoginActivity | ||
| ButterKnife.bind(this); | ||
|
|
||
| _loginButton.setOnClickListener(new View.OnClickListener() { | ||
|
|
||
| @Override | ||
| public void onClick(View v) { | ||
| login(); | ||
| } | ||
| }); | ||
|
|
||
| // Views | ||
| // mStatusTextView = (TextView) findViewById(R.id.status); | ||
|
|
||
| // Button listeners | ||
| findViewById(R.id.sign_in_button).setOnClickListener(this); | ||
| findViewById(R.id.sign_out_button).setOnClickListener(this); | ||
| findViewById(R.id.disconnect_button).setOnClickListener(this); | ||
|
|
||
| // [START configure_signin] | ||
| // Configure sign-in to request the user's ID, email address, and basic | ||
| // profile. ID and basic profile are included in DEFAULT_SIGN_IN. | ||
| GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) | ||
| .requestEmail() | ||
| .build(); | ||
| // [END configure_signin] | ||
|
|
||
| // [START build_client] | ||
| // Build a GoogleApiClient with access to the Google Sign-In API and the | ||
| // options specified by gso. | ||
| mGoogleApiClient = new GoogleApiClient.Builder(this) | ||
| .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) | ||
| .addApi(Auth.GOOGLE_SIGN_IN_API, gso) | ||
| .build(); | ||
| // [END build_client] | ||
|
|
||
| // [START customize_button] | ||
| // Set the dimensions of the sign-in button. | ||
| SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button); | ||
| signInButton.setSize(SignInButton.SIZE_STANDARD); | ||
| // [END customize_button] | ||
| } | ||
|
|
||
| public void login() { | ||
| Log.d(TAG, "Login"); | ||
|
|
||
| if (!validate()) { | ||
| onLoginFailed(); | ||
| return; | ||
| } | ||
|
|
||
| _loginButton.setEnabled(false); | ||
|
|
||
| final ProgressDialog progressDialog = new ProgressDialog(googleSignActivity.this, | ||
| R.style.AppTheme_Dark_Dialog); | ||
| progressDialog.setIndeterminate(true); | ||
| progressDialog.setMessage("Authenticating..."); | ||
| progressDialog.show(); | ||
|
|
||
| String email = _emailText.getText().toString(); | ||
| String password = _passwordText.getText().toString(); | ||
|
|
||
| // TODO: Implement your own authentication logic here. | ||
|
|
||
| new android.os.Handler().postDelayed( | ||
| new Runnable() { | ||
| public void run() { | ||
| // On complete call either onLoginSuccess or onLoginFailed | ||
| onLoginSuccess(); | ||
| // onLoginFailed(); | ||
| progressDialog.dismiss(); | ||
| } | ||
| }, 3000); | ||
| } | ||
|
|
||
| @Override | ||
| public void onBackPressed() { | ||
| // Disable going back to the MainActivity | ||
| moveTaskToBack(true); | ||
| } | ||
|
|
||
| public void onLoginSuccess() { | ||
| _loginButton.setEnabled(true); | ||
| //finish(); | ||
| Intent intent = new Intent(googleSignActivity.this,MainActivity.class); | ||
| startActivity(intent); | ||
| } | ||
|
|
||
| public void onLoginFailed() { | ||
| Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show(); | ||
|
|
||
| _loginButton.setEnabled(true); | ||
| } | ||
|
|
||
| public boolean validate() { | ||
| boolean valid = true; | ||
|
|
||
| String email = _emailText.getText().toString(); | ||
| String password = _passwordText.getText().toString(); | ||
|
|
||
| if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) { | ||
| _emailText.setError("enter a valid email address"); | ||
| valid = false; | ||
| } else { | ||
| _emailText.setError(null); | ||
| } | ||
|
|
||
| if (password.isEmpty() || password.length() < 4 || password.length() > 10) { | ||
| _passwordText.setError("between 4 and 10 alphanumeric characters"); | ||
| valid = false; | ||
| } else { | ||
| _passwordText.setError(null); | ||
| } | ||
| return valid; | ||
| } | ||
|
|
||
| @Override | ||
| public void onStart() { | ||
| super.onStart(); | ||
|
|
||
| OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient); | ||
| if (opr.isDone()) { | ||
| // If the user's cached credentials are valid, the OptionalPendingResult will be "done" | ||
| // and the GoogleSignInResult will be available instantly. | ||
| // and the GoogleSignInResult will be available instantly. | ||
| Log.d(TAG, "Got cached sign-in"); | ||
| GoogleSignInResult result = opr.get(); | ||
| handleSignInResult(result); | ||
| } else { | ||
|
|
||
| // If the user has not previously signed in on this device or the sign-in has expired, | ||
| // this asynchronous branch will attempt to sign in the user silently. Cross-device | ||
| // single sign-on will occur in this branch. | ||
| showProgressDialog(); | ||
| opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { | ||
| @Override | ||
| public void onResult(GoogleSignInResult googleSignInResult) { | ||
| hideProgressDialog(); | ||
| handleSignInResult(googleSignInResult); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| protected void onResume() { | ||
| super.onResume(); | ||
| hideProgressDialog(); | ||
| } | ||
|
|
||
| // [START onActivityResult] | ||
| @Override | ||
| public void onActivityResult(int requestCode, int resultCode, Intent data) { | ||
| super.onActivityResult(requestCode, resultCode, data); | ||
|
|
||
| if (requestCode == REQUEST_SIGNUP) { | ||
| if (resultCode == RESULT_OK) { | ||
|
|
||
| // TODO: Implement successful signup logic here | ||
| // By default we just finish the Activity and log them in automatically | ||
| this.finish(); | ||
| } | ||
| } | ||
|
|
||
| // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); | ||
| if (requestCode == RC_SIGN_IN) { | ||
| GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); | ||
| handleSignInResult(result); | ||
| } | ||
| } | ||
| // [END onActivityResult] | ||
|
|
||
| // [START handleSignInResult] | ||
| private void handleSignInResult(GoogleSignInResult result) { | ||
| Log.d(TAG, "handleSignInResult:" + result.isSuccess()); | ||
| if (result.isSuccess()) { | ||
| // Signed in successfully, show authenticated UI. | ||
| GoogleSignInAccount acct = result.getSignInAccount(); | ||
| // mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName())); | ||
| updateUI(true); | ||
| } else { | ||
| // Signed out, show unauthenticated UI. | ||
| updateUI(false); | ||
| } | ||
| } | ||
| // [END handleSignInResult] | ||
|
|
||
| // [START signIn] | ||
| private void signIn() { | ||
| Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); | ||
| startActivityForResult(signInIntent, RC_SIGN_IN); | ||
| } | ||
| // [END signIn] | ||
|
|
||
| // [START signOut] | ||
| private void signOut() { | ||
| Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( | ||
| new ResultCallback<Status>() { | ||
| @Override | ||
| public void onResult(Status status) { | ||
| // [START_EXCLUDE] | ||
| updateUI(false); | ||
| // [END_EXCLUDE] | ||
| } | ||
| }); | ||
| } | ||
| // [END signOut] | ||
|
|
||
| // [START revokeAccess] | ||
| private void revokeAccess() { | ||
| Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback( | ||
| new ResultCallback<Status>() { | ||
| @Override | ||
| public void onResult(Status status) { | ||
| // [START_EXCLUDE] | ||
| updateUI(false); | ||
| // [END_EXCLUDE] | ||
| } | ||
| }); | ||
| } | ||
| // [END revokeAccess] | ||
|
|
||
| @Override | ||
| public void onConnectionFailed(ConnectionResult connectionResult) { | ||
| // An unresolvable error has occurred and Google APIs (including Sign-In) will not | ||
| // be available. | ||
| Log.d(TAG, "onConnectionFailed:" + connectionResult); | ||
| } | ||
|
|
||
| @Override | ||
| protected void onStop() { | ||
| super.onStop(); | ||
| if (mProgressDialog != null) { | ||
| mProgressDialog.dismiss(); | ||
| } | ||
| } | ||
|
|
||
| private void showProgressDialog() { | ||
| if (mProgressDialog == null) { | ||
| mProgressDialog = new ProgressDialog(this); | ||
| mProgressDialog.setMessage(getString(R.string.loading)); | ||
| mProgressDialog.setIndeterminate(true); | ||
| } | ||
|
|
||
| mProgressDialog.show(); | ||
| } | ||
|
|
||
| private void hideProgressDialog() { | ||
| if (mProgressDialog != null && mProgressDialog.isShowing()) { | ||
| mProgressDialog.hide(); | ||
| } | ||
| } | ||
|
|
||
| private void updateUI(boolean signedIn) { | ||
| if (signedIn) { | ||
| findViewById(R.id.sign_in_button).setVisibility(View.GONE); | ||
| //findViewById(R.id.sign_out_and_disconnect).setVisibility(View.VISIBLE); | ||
|
|
||
| Intent intent = new Intent(googleSignActivity.this,MainActivity.class); | ||
| startActivity(intent); | ||
|
|
||
| } else { | ||
| //mStatusTextView.setText(R.string.signed_out); | ||
|
|
||
| findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE); | ||
| findViewById(R.id.sign_out_and_disconnect).setVisibility(View.GONE); | ||
|
|
||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void onClick(View v) { | ||
| switch (v.getId()) { | ||
| case R.id.sign_in_button: | ||
| signIn(); | ||
| break; | ||
| case R.id.sign_out_button: | ||
| signOut(); | ||
| break; | ||
| case R.id.disconnect_button: | ||
| revokeAccess(); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
| @@ -10,7 +10,6 @@ | ||
| import android.widget.EditText; | ||
| import android.widget.TextView; | ||
| import android.widget.Toast; | ||
| import com.example.hunter.planstart.R; | ||
|
|
||
| import butterknife.Bind; | ||
| @@ -0,0 +1,39 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <LinearLayout | ||
| android:id="@+id/main_layout" | ||
| android:orientation="vertical" | ||
| xmlns:android="http://schemas.android.com/apk/res/android" | ||
| xmlns:app="http://schemas.android.com/apk/res-auto" | ||
| xmlns:tools="http://schemas.android.com/tools" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="match_parent" | ||
| tools:context="com.example.hunter.planstart.MainActivity"> | ||
|
|
||
| <!-- our toolbar --> | ||
| <android.support.v7.widget.Toolbar | ||
| android:id="@+id/toolbar" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:background="?attr/colorPrimary" | ||
| android:minHeight="?attr/actionBarSize" | ||
| android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" | ||
| app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> | ||
|
|
||
| <!-- our tablayout to display tabs --> | ||
| <android.support.design.widget.TabLayout | ||
| android:id="@+id/tabLayout" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:background="?attr/colorPrimary" | ||
| android:minHeight="?attr/actionBarSize" | ||
| app:tabIndicatorColor="@color/black" | ||
| app:tabIndicatorHeight="3dp" | ||
| android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> | ||
|
|
||
| <!-- View pager to swipe views --> | ||
| <android.support.v4.view.ViewPager | ||
| android:id="@+id/pager" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="fill_parent"/> | ||
|
|
||
| </LinearLayout> |
| @@ -0,0 +1,180 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| xmlns:tools="http://schemas.android.com/tools" | ||
| android:id="@+id/main_layout" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="match_parent" | ||
| android:orientation="vertical" | ||
| android:weightSum="4" | ||
| tools:context=".MainActivity"> | ||
|
|
||
| <LinearLayout | ||
| android:orientation="vertical" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:paddingTop="56dp" | ||
| android:paddingLeft="24dp" | ||
| android:paddingRight="24dp"> | ||
|
|
||
| <ImageView android:src="@drawable/logo" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="72dp" | ||
| android:layout_marginBottom="24dp" | ||
| android:layout_gravity="center_horizontal" /> | ||
|
|
||
| <!-- Email Label --> | ||
| <android.support.design.widget.TextInputLayout | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="8dp" | ||
| android:layout_marginBottom="8dp"> | ||
| <EditText android:id="@+id/input_email" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:inputType="textEmailAddress" | ||
| android:hint="Email" /> | ||
| </android.support.design.widget.TextInputLayout> | ||
|
|
||
| <!-- Password Label --> | ||
| <android.support.design.widget.TextInputLayout | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="8dp" | ||
| android:layout_marginBottom="8dp"> | ||
| <EditText android:id="@+id/input_password" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:inputType="textPassword" | ||
| android:hint="Password"/> | ||
| </android.support.design.widget.TextInputLayout> | ||
|
|
||
| <android.support.v7.widget.AppCompatButton | ||
| android:id="@+id/btn_login" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="24dp" | ||
| android:layout_marginBottom="24dp" | ||
| android:padding="12dp" | ||
| android:text="Login"/> | ||
|
|
||
| <!--<TextView android:id="@+id/link_signup" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginBottom="24dp" | ||
| android:text="No account yet? Create one" | ||
| android:gravity="center" | ||
| android:textSize="16dip"/>--> | ||
| <TextView | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginBottom="24dp" | ||
| android:text="OR" | ||
| android:gravity="center" | ||
| android:textSize="16dip" | ||
| /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <!--- <LinearLayout | ||
| android:layout_width="match_parent" | ||
| android:layout_height="0dp" | ||
| android:layout_weight="3" | ||
| android:gravity="center_horizontal" | ||
| android:orientation="vertical"> | ||
| <ImageView | ||
| android:id="@+id/google_icon" | ||
| android:layout_width="48dp" | ||
| android:layout_height="48dp" | ||
| android:layout_marginBottom="10dp" | ||
| android:layout_marginTop="@dimen/g_top_margin" | ||
| android:contentDescription="@string/desc_google_icon"/> | ||
| <TextView | ||
| android:id="@+id/title_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginBottom="10dp" | ||
| android:text="@string/title_text" | ||
| android:gravity="center" | ||
| android:textColor="@android:color/white" | ||
| android:textSize="36sp" /> | ||
| <TextView | ||
| android:id="@+id/status" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:text="@string/signed_out" | ||
| android:textColor="@android:color/white" | ||
| android:textSize="14sp" /> | ||
| <TextView | ||
| android:id="@+id/detail" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:fadeScrollbars="true" | ||
| android:gravity="center" | ||
| android:maxLines="5" | ||
| android:padding="10dp" | ||
| android:scrollbars="vertical" | ||
| android:textColor="@android:color/white" | ||
| android:textSize="14sp" /> | ||
| <Button | ||
| android:id="@+id/button_optional_action" | ||
| style="@style/Base.Widget.AppCompat.Button.Borderless.Colored" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:visibility="gone" | ||
| tools:text="Optional Action" | ||
| tools:visibility="visible" /> | ||
| </LinearLayout>--> | ||
|
|
||
|
|
||
| <RelativeLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="0dp" | ||
| android:layout_weight="1" | ||
| android:background="@color/blue_grey_900"> | ||
|
|
||
| <com.google.android.gms.common.SignInButton | ||
| android:id="@+id/sign_in_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_centerInParent="true" | ||
| android:visibility="visible" | ||
| tools:visibility="gone" /> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/sign_out_and_disconnect" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_centerInParent="true" | ||
| android:orientation="horizontal" | ||
| android:paddingLeft="16dp" | ||
| android:paddingRight="16dp" | ||
| android:visibility="gone" | ||
| tools:visibility="visible"> | ||
|
|
||
| <Button | ||
| android:id="@+id/sign_out_button" | ||
| android:layout_width="0dp" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:text="@string/sign_out" | ||
| /> | ||
|
|
||
| <Button | ||
| android:id="@+id/disconnect_button" | ||
| android:layout_width="0dp" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:text="@string/disconnect" | ||
| /> | ||
| </LinearLayout> | ||
|
|
||
| </RelativeLayout> | ||
|
|
||
| </LinearLayout> |
| @@ -0,0 +1,18 @@ | ||
| <?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:orientation="vertical" | ||
| android:background="@color/white" | ||
| > | ||
|
|
||
| <TextView | ||
| android:id="@+id/textView" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_centerInParent="true" | ||
| android:text="Chat Room" | ||
| android:background="@color/white" | ||
| android:textAppearance="?android:attr/textAppearanceLarge"/> | ||
|
|
||
| </RelativeLayout> |
| @@ -0,0 +1,17 @@ | ||
| <?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:orientation="vertical" | ||
| android:background="@color/white"> | ||
|
|
||
| <TextView | ||
| android:id="@+id/textView" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_centerInParent="true" | ||
| android:text="Venue" | ||
| android:textAppearance="?android:attr/textAppearanceLarge"/> | ||
|
|
||
| </RelativeLayout> |
| @@ -0,0 +1,48 @@ | ||
| { | ||
| "project_info": { | ||
| "project_number": "720284306859", | ||
| "project_id": "firebase-planstart" | ||
| }, | ||
| "client": [ | ||
| { | ||
| "client_info": { | ||
| "mobilesdk_app_id": "1:720284306859:android:2cf2529378bb4f0d", | ||
| "android_client_info": { | ||
| "package_name": "com.example.hunter.planstart" | ||
| } | ||
| }, | ||
| "oauth_client": [ | ||
| { | ||
| "client_id": "720284306859-uc7or7qaq119vmjhjdhrfapru1hi4s6r.apps.googleusercontent.com", | ||
| "client_type": 1, | ||
| "android_info": { | ||
| "package_name": "com.example.hunter.planstart", | ||
| "certificate_hash": "85cf4d03c760ae8cdff3eea28b13f4e37a1d3182" | ||
| } | ||
| }, | ||
| { | ||
| "client_id": "720284306859-biu8sqagen7an3nseep8a8qui721iivj.apps.googleusercontent.com", | ||
| "client_type": 3 | ||
| } | ||
| ], | ||
| "api_key": [ | ||
| { | ||
| "current_key": "AIzaSyDnh-_RWvGsW0vtqs_-fjb22CPj_1g0ffg" | ||
| } | ||
| ], | ||
| "services": { | ||
| "analytics_service": { | ||
| "status": 1 | ||
| }, | ||
| "appinvite_service": { | ||
| "status": 1, | ||
| "other_platform_oauth_client": [] | ||
| }, | ||
| "ads_service": { | ||
| "status": 1 | ||
| } | ||
| } | ||
| } | ||
| ], | ||
| "configuration_version": "1" | ||
| } |