How to Get Value from JSON in Firebase Remote Config - java

I am a novice to Android app development and Firebase.
I want to know how can I get the value (String & Int) in the JSONArray file stored in Firebase Remote Config?
I use Firebase Remote Config with the final goal to compare my app's version code and priority level with the one stored in Firebase Remote Config to determine initiation of App Update notification, but so far I still unable get Remote Config value.
I tried to parse the JSON using Volley (jsonParse in MainActivity2 class), but it also didn't work. (Error bad url)
I have several times tried to implement previous answers, but maybe because of my misunderstanding, all those came to no avail.
Can I declare an array to Firebase Remote config?
Can I get JSONObject from Default value of Firebase Remote Config
FirebaseRemoteConfig getString is empty
I also have read this interesting article about implementing in-app updates notifications with some specific criteria using Remote Config, but unfortunately for me, the codes are written in Kotlin.
https://engineering.q42.nl/android-in-app-updates/
test_json file stored in Firebase Remote Config.
[
{
"versionCode": "1",
"priorityLevel": 2
},
{
"versionCode": "2",
"priorityLevel": 4
},
{
"versionCode": "3",
"priorityLevel": 1
}
]
MainActivity2 class
remoteConfig = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
.setFetchTimeoutInSeconds(2000)
.build();
remoteConfig.setConfigSettingsAsync(configSettings);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
remoteConfig.fetchAndActivate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
#Override
public void onComplete(#NonNull Task<Boolean> task) {
if (task.isSuccessful()) {
String object = remoteConfig.getString("test_json");
//jsonParse(object);
Gson gson = new GsonBuilder().create();
ArrayList<Lessons> lessons = gson.fromJson(object,
new TypeToken<List<Lessons>>(){}.getType());
} else {
Toast.makeText(MainActivity2.this, "Fetch Failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
});
private void jsonParse(String object) {
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, object, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("condition");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject condition = jsonArray.getJSONObject(i);
String versionCode = condition.getString("versionCode");
int priorityLevel = condition.getInt("priorityLevel");
textView.append(versionCode + "\n\n");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mQueue.add(request);
}
Lessons class
public class Lessons {
String versionCode;
Int priorityLevel;
}
Any help would be greatly appreciated.
Thank you.

For me worked like that
import com.google.gson.annotations.SerializedName
data class VersionData(
#SerializedName("name")
val name: String,
#SerializedName("age")
var age: Int,
#SerializedName("isFemale")
var isFemale: Boolean
)
init {
remoteConfig.fetchAndActivate()
}
private val _mutableLiveData = MutableLiveData<VersionData>()
val remoteLiveData: LiveData<VersionData> = _mutableLiveData
fun remoteConfiguration() {
val gson = Gson()
val remote = remoteConfig.fetchAndActivate()
remote.addOnSuccessListener{
val stringJson = remoteConfig.getString("json_object_name")
if(stringJson.isNotEmpty()){
val jsonModel = gson.fromJson(stringJson, VersionData::class.java)
_mutableLiveData.value = VersionData(
name = jsonModel.name,
age = jsonModel.age,
isFemale = jsonModel.isFemale
)
}else{
// probably your remote param not exists
}
}
}
so observe in compose
val localLifecycle = LocalLifecycleOwner.current
myViewModel.remoteLiveData.observe(localLifecycle){
Log.d("remoteLiveData", "remoteLiveData: $it")
}

I recommend you use Gson.
data class Lessons(
val versionCode: String? = null,
val priorityLevel: Int? = null
)
and then, use getValue() or getString() to get the data.
val list = Gson().fromJson(getValue("test_json").asString(), Array<Lessons>::class.java)
In my case, getString() also worked.
val list = Gson().fromJson(getString("test_json"), Array<Lessons>::class.java)
This is simpler.

Related

How can I add data to Firebase database?

I think I wrote the codes correctly, but Firebase does not add data in Realtime Database. I downloaded the JSON file, connected the project, checked it via Firebase tools, but it still doesn't add data. What can I do it?
Mainactivity.java - addevent class(it will work when click the button)
private void addEvent(){
String plan = etplan.getText().toString();
String note = etnote.getText().toString();
String date = etdate.getText().toString();
String time = ettime.getText().toString();
String remb = "false";
if (remember.isChecked()==true){
remb = "true";
}
else{
remb = "false";
}
String id = dbRef.push().getKey();
Events event = new Events(id,plan,note,date,time,remb);
dbRef.child(id).setValue(event);
}
I get the following error in the Run section of the program:
glUtilsParamSize: unknow param at 0x000082
And edited this code:
dbRef.child(id).setValue(event)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(MainActivity.this,"Events Added SUCCESSFULLY!", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this,e.toString(), Toast.LENGTH_SHORT).show();
}
});

Java Android Studio cannot send ArrayList from another class to MainActivity

I try to add data from my object to ArrayList but it's not work.
This code read data from JSON and add to ArrayList in MySQLConnect.java like this.
private ComputerService computerservice;
public static ArrayList<ComputerService> computerServicesArrayList = new ArrayList<>();
private String URL = "http://10.200.100.10/", GET_URL = "android/get_data.php";
public MySQLConnect(){
main = null;
}
public MySQLConnect(Activity mainA){
main = mainA;
}
public List<ComputerService> getData(){
String url = URL + GET_URL;
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(main, error.getMessage().toString(), LENGTH_LONG).show();
}
}
);
RequestQueue requestQueue = Volley.newRequestQueue(main.getApplicationContext());
requestQueue.add(stringRequest);
return computerServicesArrayList;
}
public void showJSON(String response){
String data_mysql = "";
computerServicesArrayList.clear();
try{
JSONObject jsonObject = new JSONObject(response);
JSONArray result = jsonObject.getJSONArray("data");
for(int i=0; i < result.length(); i++){
JSONObject collectData = result.getJSONObject(i);
String id = collectData.getString("id");
String type = collectData.getString("type");
String address = collectData.getString("address");
computerservice = new ComputerService(id, type, address);
computerServicesArrayList.add(computerservice);
}
System.out.println("Size in class MySQLConnect");
System.out.println(computerServicesArrayList.size());
} catch (JSONException e) {
e.printStackTrace();
}
}
The MainActivity.java I show computerServicesArrayList.size() like this.
public static List<ComputerService> computerServicesArrayList;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySQLConnect = new MySQLConnect(MainActivity.this);
update();
}
public void update(){
computerServicesArrayList = mySQLConnect.getData();
System.out.println("Size in MainActivity");
System.out.println(computerServicesArrayList.size());
}
The output show like this.
Size in MainActivity
0
Size in class MySQLConnect
83
From the code I can print computerServicesArrayList.size() the result is 83 but when I print from MainActivity why it show result 0. How to fix it?
I don't know the Volley framework/classes in detail. But it looks like you are creating an asynchronous request. So your rest-request gets send and when the response comes in your showJSON() method is called.
But you immediatley return the computerServicesArrayList result, which is empty because you don't have your response yet. This is also the reason why the print statement from your MainActivity is executed before the print from your showJSON method.
If you want to wait for the rest-response you have to do synchronous requests.
Maybe this can help you more about Volley and asyn/sync requests:
how to wait the volley response to finish it's work inside intentservice?
Can I do a synchronous request with volley?
But normally you would send an async-request and when you get the response you do your logic (update fields, store something in database, ...).
Your computerServicesArrayList is populated by callback from Volley (new Response.Listener()). This population happens correctly as you have verified. But it does take some time, for the network up/down travel. When your MainActivity's call to mySQLConnect.getData() returns this round trip is not complete yet; so you get an empty list in MainActivity.
The usual solution to this problem is to make the listener call methods in MainActivity. This can be done by making
class MainActivity implements Response.Listener<String> {
/* --- */
#Override
public void onResponse(String response) {
showJSON(response);
}
void showJSON(String response){
// Do the stuff here
}

How to get PaymentMethodNonce and deviceData on Braintree Android PayPal Vault Payment

Am trying to implement Braintree Vault PayPal payment, the problem am facing here is getting the paymentMethodNonce my event listener createdListener to capture nonce doesn't get called using vault, but everything works fine using checkout. I can't charge customer without a paymentMethodNonce, please can anyone assist me.
mBraintreeFragment = BraintreeFragment.newInstance(this,"TOKEN_FROM_SERVER");
PayPalRequest request = new PayPalRequest().localeCode("US").billingAgreementDescription("Your agreement description");
PayPal.requestBillingAgreement(mBraintreeFragment, request);
mBraintreeFragment.addListener(createdListener);
mBraintreeFragment.addListener(cancelListener);
mBraintreeFragment.addListener(errorListener);
DataCollector.collectDeviceData(mBraintreeFragment, new BraintreeResponseListener<String>() {
#Override
public void onResponse(String deviceData) {
Log.e("PayPal", deviceData);
try {
JSONObject json = new JSONObject(deviceData);
deviceDataInfo = json.getString("correlation_id");
Log.e("PayPal", deviceDataInfo);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
My Listeners
PaymentMethodNonceCreatedListener createdListener = new PaymentMethodNonceCreatedListener() {
#Override
public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) {
String nonce = paymentMethodNonce.getNonce();
Log.d("PayPal", "nonce id " + nonce);
}
};
BraintreeCancelListener cancelListener = new BraintreeCancelListener() {
#Override
public void onCancel(int requestCode) {
Log.d("CreditCard", "Braintree Error Code " + requestCode);
}
};
BraintreeErrorListener errorListener = new BraintreeErrorListener() {
#Override
public void onError(Exception error) {
if (error instanceof ErrorWithResponse) {
ErrorWithResponse errorWithResponse = (ErrorWithResponse) error;
BraintreeError cardErrors = errorWithResponse.errorFor("creditCard");
if (cardErrors != null) {
List<BraintreeError> errors = cardErrors.getFieldErrors();
String err = Objects.requireNonNull(errors.get(0).getMessage());
Log.d("CreditCard", errors.toString());
}
}
}
};
Instead of adding manually your listeners to that request, it's better to just implement the interface from braintree.
For example, if you want to use the onPaymentMethodNonceCreated() just add "implements PaymentMethodNonceCreatedListener" after your class name.
public class "YourClass" implements PaymentMethodNonceCreatedListener {
//...
}
And then override the method that now the Android Studio is warning you:
#Override
public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) {
String nonce = paymentMethodNonce.getNonce();
//...
}
This way you can go for everyone of your listeners! Good luck!

How can I store list items when there is no internet connection (data come from server)

Regarding
I have a listview contains 4 items 3 of them are texts and fourth is image
all data are on server within json
the code work correctly but when the internet is off all items and list does not appear how can make the list works with and without internet connection
because I add everyday new items to database
and this my code
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("allstudents");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject respons = jsonArray.getJSONObject(i);
String id = respons.getString("id");
String name = respons.getString("name");
String info = respons.getString("info");
String img = respons.getString("img");
link = respons.getString("link");
voicelink = respons.getString("voicelink");
listitmes.add(new listitme(id, name, info, img, link, voicelink));
allitems();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", "ERROR");
}
}
);
requestQueue.add(jsonObjectRequest);
}
public void allitems() {
listAdapter lsadapter = new listAdapter(listitmes);
listView.setAdapter(lsadapter);
}
any solution please I searched a lot but no any answer
and I did not find any thing like here on StackOverflow.Com
Look at https://developer.android.com/reference/android/content/SharedPreferences.
With Shared SharedPreferences you can save the list and call it if there is no wifi!
what you can do is:
Save the data that you download, to a file (image)/properties (text) as soon as you receive data from Internet. ()
Display a message in your activity when the data was fetched (e.g. Last Synced : Timestamp).
If you can can't connect to Internet to get the new data, load the data from file/properties.
If you can't connect to Internet and don't have any saved data, display a message (e.g. can't connect to Internet - may be color it to highlight it's an error).
my 2 cents...

Converting Android Volley Request to iOS NSURL asynchronous request

I have the following method in my Android app which I use for user login/registration.
public void registerUser(final String username, final String email, final String password) {
pDialog.setMessage("Signing Up...");
pDialog.show();
request = new StringRequest(Method.POST, SL_URL, new Response.Listener<String>() {
#Override
public void onResponse(String s) {
pDialog.dismiss();
String[] split = s.split("Config.php");
String after = split[1];
try {
JSONObject jsonObject = new JSONObject(after);
boolean error = jsonObject.getBoolean("error");
if (error) {
String errorMsg = jsonObject.getString("error_msg");
Toast.makeText(getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
} else {
session.setLogin(true, username, email);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("tag", "login");
hashMap.put("username", name);
hashMap.put("password", password);
return hashMap;
}
};
queue.add(request);
}
Now I am writing my app for iOS and trying to replicate this in Swift. So far I have the following code:
let username = usernameTxt.text
let password = passwordTxt.text
let urlPath: String = "***"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "POST"
let stringPost="tag=login&username=" + username! + "&password=" + password! // Key and Value
NSLog(stringPost)
let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)
request1.timeoutInterval = 60
request1.HTTPBody=data
request1.HTTPShouldHandleCookies=false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do {
var jsonResult: NSDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
} catch _ {}
})
Now as someone new to iOS development and Swift in general, I have the following questions:
What is the best way to replicate the progressDialog I use in Java in Swift, it must be visible until the request is complete and then it should be dismissed. I'm guessing this should be placed in the completionHandler, however I'm not sure which UI element to use for the progress Dialog.
How do I obtain my response as a String and replicate the behaviour of the split function, and then convert the result of this into a jsonObject like I do in my Java code.
What is the best way to replicate the Toast used to show the error message. I don't think using a dialog which must be closed with a button would be optimal here.
Thank you.
I am also developing Applications for Android and IOS. Here i Answered your three Problems which is faced by me also as a beginner. I hope this would help you.
1) Use MBProgressHUD Link to replicate the progressDialog in Swift .There are two method to show and dismiss the progressDialog:
Use showLoadingHUD() before making HTTP request
private func showLoadingHUD() {
let hud = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
hud.labelText = "Loading..."
}
And hideLoadingHUD() after receiving the response from server
private func hideLoadingHUD() {
MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
}
2) you can use Alamofire Link which can handle Network stuff And you can easily obtain response in String.
Example:
self.showLoadingHUD()
Alamofire.request(.GET, data, parameters: nil)
.response { (request, response, data, error) in
print(data) // if you want to check data in debug window.
let Result = NSString(data: data!, encoding: NSUTF8StringEncoding)
Result!.stringByReplacingOccurrencesOfString("\"", withString: "")
if(newResult == "1"){
self.navigationController!.popViewControllerAnimated(true)
JLToast.makeText("Success").show()
}
else if (newResult == "0"){
JLToast.makeText("Failed").show()
}
self.hideLoadingHUD()
3) mankee Toas are used for a purpose of displaying information for short period of time and disappear themselves. Here we can use Android like Toast which is JLToast. Available on github .
JLToast.makeText("Success").show()

Categories

Resources