How to setting firebase remote config for unity? - unity3d

lets to the point, so i want to make some configuration with my game to show Ads but I avoid to update game version too much, because of that I choose firebase remote config with this I can update setting/configuration without update the game version.
there is document for this but not very clear for newbie like me, you can check it here https://firebase.google.com/docs/remote-config/use-config-unity
I already make the script like on doc, but I don't understand how its work on show data because error string format, which is what I know on this firebase console is int format
the script like this :
public static _FirebaseRemoteConfig instance;
private void Awake()
{
instance = this;
}
Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther;
// Use this for initialization
void Start()
{
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
InitializeFirebase();
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + dependencyStatus);
}
});
}
public void InitializeFirebase()
{
System.Collections.Generic.Dictionary<string, object> defaults =
new System.Collections.Generic.Dictionary<string, object>();
defaults.Add("config_test_string", "default local string");
defaults.Add("config_test_int", 1);
defaults.Add("config_test_float", 1.0);
defaults.Add("config_test_bool", false);
Firebase.RemoteConfig.FirebaseRemoteConfig.SetDefaults(defaults);
Debug.Log("Remote config ready!");
}
public void FetchFireBase()
{
FetchDataAsync();
}
public void ShowData()
{
Debug.Log("maxCountToShowAdmob: " +
Firebase.RemoteConfig.FirebaseRemoteConfig.GetValue("MaxCountShowIntersitialAds").LongValue);
}
// Start a fetch request.
public Task FetchDataAsync()
{
Debug.Log("Fetching data...");
System.Threading.Tasks.Task fetchTask = Firebase.RemoteConfig.FirebaseRemoteConfig.FetchAsync(
TimeSpan.Zero);
return fetchTask.ContinueWith(FetchComplete);
}
void FetchComplete(Task fetchTask)
{
if (fetchTask.IsCanceled)
{
Debug.Log("Fetch canceled.");
}
else if (fetchTask.IsFaulted)
{
Debug.Log("Fetch encountered an error.");
}
else if (fetchTask.IsCompleted)
{
Debug.Log("Fetch completed successfully!");
}
var info = Firebase.RemoteConfig.FirebaseRemoteConfig.Info;
switch (info.LastFetchStatus)
{
case Firebase.RemoteConfig.LastFetchStatus.Success:
Firebase.RemoteConfig.FirebaseRemoteConfig.ActivateFetched();
Debug.Log(String.Format("Remote data loaded and ready (last fetch time {0}).",
info.FetchTime));
break;
case Firebase.RemoteConfig.LastFetchStatus.Failure:
switch (info.LastFetchFailureReason)
{
case Firebase.RemoteConfig.FetchFailureReason.Error:
Debug.Log("Fetch failed for unknown reason");
break;
case Firebase.RemoteConfig.FetchFailureReason.Throttled:
Debug.Log("Fetch throttled until " + info.ThrottledEndTime);
break;
}
break;
case Firebase.RemoteConfig.LastFetchStatus.Pending:
Debug.Log("Latest Fetch call still pending.");
break;
}
}

Related

Respond from Volley library comes in twice

I am trying to figure out why a response from the Volley library comes in twice (and it is not always the same response that is doubled).
This is the result, a pie chart:
As we can see the total income and the total spending comes in twice (and if I debug it, it is never 4 GET calls, it is always at least 6 GET calls, although only 4 methods are executed).
Here is my code where I am trying to execute 4 GET requests.
public void initialize() {
getOutputFromDatabase(StaticFields.INCOME);
getOutputFromDatabase(StaticFields.EXPENSE);
getOutputFromDatabase(StaticFields.SAVINGS);
getOutputFromDatabase(StaticFields.FOOD);
}
private void getOutputFromDatabase(String incomeOrExpenseOrSavingsOrFood) {
//RequestQueue initialized
mRequestQueue = Volley.newRequestQueue(this);
// REST URL
String url = null;
if(incomeOrExpenseOrSavingsOrFood.equals("income")) {
url = StaticFields.PROTOCOL +
sharedPref_IP +
StaticFields.COLON +
sharedPref_Port +
StaticFields.REST_URL_GET_SUM_INCOME;
} else if (incomeOrExpenseOrSavingsOrFood.equals("expense")) {
url = StaticFields.PROTOCOL +
sharedPref_IP +
StaticFields.COLON +
sharedPref_Port +
StaticFields.REST_URL_GET_SUM_EXPENSE;
} else if (incomeOrExpenseOrSavingsOrFood.equals("savings")) {
url = StaticFields.PROTOCOL +
sharedPref_IP +
StaticFields.COLON +
sharedPref_Port +
StaticFields.REST_URL_GET_SUM_SAVINGS;
} else if (incomeOrExpenseOrSavingsOrFood.equals("food")) {
url = StaticFields.PROTOCOL +
sharedPref_IP +
StaticFields.COLON +
sharedPref_Port +
StaticFields.REST_URL_GET_SUM_FOOD;
}
//String Request initialized
StringRequest mStringRequest = new StringRequest(Request.Method.GET,
url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
JSONArray jsonArray = new JSONArray();
jsonArray.put(obj);
JSONObject locs = obj.getJSONObject("incomeexpense");
JSONArray recs = locs.getJSONArray("Total income");
String repl = recs.getString(0);
if(incomeOrExpenseOrSavingsOrFood.equals("income") && repl.equals("null")) {
totalIncome.setText("0");
} else if(incomeOrExpenseOrSavingsOrFood.equals("income") && !repl.equals("null")){
totalIncome.setText(repl);
pieChart.addPieSlice(
new PieModel(
"Total income",
Float.parseFloat(repl),
Color.parseColor("#99CC00")));
} else if(incomeOrExpenseOrSavingsOrFood.equals("expense") && repl.equals("null")) {
totalExpense.setText("0");
} else if(incomeOrExpenseOrSavingsOrFood.equals("expense") && !repl.equals("null")) {
totalExpense.setText(repl);
pieChart.addPieSlice(
new PieModel(
"Total spending",
Float.parseFloat(repl),
Color.parseColor("#FF4444")));
} else if(incomeOrExpenseOrSavingsOrFood.equals("savings") && repl.equals("null")) {
totalSavings.setText("0");
} else if(incomeOrExpenseOrSavingsOrFood.equals("savings") && !repl.equals("null")) {
totalSavings.setText(repl);
pieChart.addPieSlice(
new PieModel(
"Total savings",
Float.parseFloat(repl),
Color.parseColor("#33B5E5")));
} else if(incomeOrExpenseOrSavingsOrFood.equals("food") && repl.equals("null")) {
totalFood.setText("0");
} else if(incomeOrExpenseOrSavingsOrFood.equals("food") && !repl.equals("null")) {
totalFood.setText(repl);
pieChart.addPieSlice(
new PieModel(
"Food/day",
Float.parseFloat(repl),
Color.parseColor("#FFBB33")));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG,"Error :" + error.toString());
}
});
mStringRequest.setShouldCache(false);
DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(5000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
mStringRequest.setRetryPolicy(retryPolicy);
mRequestQueue.add(mStringRequest);
// To animate the pie chart
pieChart.startAnimation();
}
Maybe someone know what I am doing wrong here?
I tried different things like
disabling the cache
setting a policy
but nothing worked so far.
I found my error.
The problem is that I am calling my methods where we can find the REST API calls in onResume again.
I had in my mind that onResume is called when someone comes back to his Activity, but I was wrong.
This is my right onResume now.
#Override
protected void onResume() {
super.onResume();
// pieChart.clearChart();
loadSharedPreferences(StaticFields.SP_PORT);
loadSharedPreferences(StaticFields.SP_INTERNET_ADDRESS);
loadSharedPreferences(StaticFields.SP_PERSON);
// getOutputFromDatabase(StaticFields.INCOME);
// getOutputFromDatabase(StaticFields.EXPENSE);
// getOutputFromDatabase(StaticFields.SAVINGS);
// getOutputFromDatabase(StaticFields.FOOD);
// To animate the pie chart
pieChart.startAnimation();
resetEditText();
}

DeveloperError Exception of type 'Google.GoogleSignIn+SignInException', googleplaystore, unity, google login?

I have weird behaviour for my SignInWithGoogle.
I have everything set up for QAuth, SSH, WebClieng etc.
And when I sent a build to my phone directly. All work fine. I can SignIn, LogIn etc.
But when I made an aab build and uploaded it to google console and downloaded it from GooglePlay, as a tester, I received DeveloperError Exception of type 'Google.GoogleSignIn+SignInException.
Is there maybe something I need to change on QAuth to fix that?
public class SignInWithGoogle : MonoBehaviour
{
public static string slaveUserEmail;
public static string slaveUserPassword;
string webClientId = "536446807232-vh3olku8c637olltqlge92p17qmsqmtl.apps.googleusercontent.com";
private GoogleSignInConfiguration configuration;
FirebaseAuth _auth;
bool _initialized = false;
void Awake()
{
FireBaseInit.OnInitialized += OnFirebaseInit;
configuration = new GoogleSignInConfiguration
{
WebClientId = webClientId,
RequestIdToken = true
};
}
public void OnFirebaseInit()
{
if (_initialized) return;
_auth = FirebaseAuth.DefaultInstance;
_initialized = true;
Debug.Log("GoogleAuth Initialized");
}
public void OnSignIn()
{
Debug.Log("Calling SignIn");
GoogleSignIn.Configuration = configuration;
GoogleSignIn.Configuration.UseGameSignIn = false;
GoogleSignIn.Configuration.RequestIdToken = true;
var signInCompleted = new TaskCompletionSource<FirebaseUser>();
Debug.Log("SignInInit");
try
{
GoogleSignIn.DefaultInstance.SignIn().ContinueWith(task =>
{
if (task.IsFaulted)
{
using (IEnumerator<Exception> enumerator =
task.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
GoogleSignIn.SignInException error =
(GoogleSignIn.SignInException)enumerator.Current;
Debug.Log("Got Error: " + error.Status + " " + error.Message);
}
else
{
Debug.Log("Got Unexpected Exception?!?" + task.Exception);
}
}
}
else if (task.IsCanceled)
{
Debug.Log("Canceled");
}
else
{
Debug.Log("Welcome in Google: " + task.Result.DisplayName + "!");
Debug.Log("GEt Ceds");
Credential credential = GoogleAuthProvider.GetCredential(task.Result.IdToken, null);
Debug.Log("Creds added");
Debug.Log("Firebase Log In try!");
FirebaseAuth.DefaultInstance.SignInWithCredentialAsync(credential).ContinueWith(authTask =>
{
if (authTask.IsCanceled)
{
Debug.Log("Auth Canceld");
signInCompleted.SetCanceled();
}
else if (authTask.IsFaulted)
{
Debug.Log("Auth Faulted");
signInCompleted.SetException(authTask.Exception);
}
else
{
Debug.Log("Auth Coplited");
signInCompleted.SetResult(((Task<FirebaseUser>)authTask).Result);
}
});
}
});
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
The full error:
Got Error: DeveloperError Exception of type 'Google.GoogleSignIn+SignInException' was thrown. <>c__DisplayClass8_0:b__0(Task`1) System.Threading.ThreadPoolWorkQueue:Dispatch()

How to properly forward/redirect calls with pjsua2

I can't find info on the net how to forward a call with pjsua2.
Currently Im trying with the xfer method but Im getting:
../src/pjsip-ua/sip_inv.c:3942: inv_on_state_null: Assertion `!"Unexpected transaction type"' failed.
There is no information about this error.
This is my code Im trying:
void MyAccount::onIncomingCall(OnIncomingCallParam &iprm)
{
MyCall *call = new MyCall(*this, iprm.callId);
...
calls.push_back(call);
...
QString fwd_to = fwd(QString::fromStdString(ci.remoteUri));
if(fwd_to != "NO_FWD")
{
info+="*** Xfer Call: ";
info+=QString::fromStdString(ci.remoteUri);
info+=" [";
info+=QString::fromStdString(ci.stateText);
info+="]\n";
infoChanged=true;
CallOpParam prm1;
prm1.statusCode = (pjsip_status_code)200;
call->answer(prm1);
pj_thread_sleep(2000);
CallOpParam prm2(true);
call->xfer(fwd_to.toStdString(), prm2);
}
else
{
// standart incoming
...
}
}
fwd is my own function which search a database if it needs to forward the call
I did something like this and works, dont know if some other way exist:
(answering with no media, setting flag and in other thread xfering call to fwd_to string)
if(fwd_to != "NO_FWD")
{
CallOpParam prm1;
prm1.statusCode = (pjsip_status_code)200;
call->answer(prm1);
call->fwd_to = fwd_to;
call->fwd=true;
}
FwdThread *fwd_thread = new FwdThread();
fwd_thread->start();
void FwdThread::run()
{
static pj_thread_desc s_desc;
static pj_thread_t *s_thread;
pj_thread_register("FwdThread", s_desc, &s_thread);
loop();
}
void FwdThread::loop()
{
while(1)
{
for(auto &call : pjt->v_calls)
{
if(call->fwd && call->answered)
{
call->fwd=false;
CallOpParam prm2(true);
call->xfer(call->fwd_to.toStdString(), prm2);
}
}
if(pjt->Stop)
break;
pj_thread_sleep(500);
}
}

ZK UI update on Database data changes

How can I update data on UI when someting changes on database?
I want that my UI automatically update data when I changes record on my database (with a common database viewer) like Facebook does when someone friend publish something on the clipboard (without refresh)
You can use polling or pushing.
For pushing you could extend SelectorComposer
and apply to your zul
public class ComposerPush extends SelectorComposer<Component> {
private static final long serialVersionUID = 1L;
// wire components
#Wire
ZHighCharts chartComp;
// Basic Line
private SimpleExtXYModel dataChartModel = new SimpleExtXYModel();
public void startWorker() {
final Desktop desktop = Executions.getCurrent().getDesktop();
if (desktop.isServerPushEnabled()) {
} else {
desktop.enableServerPush(true);
if(timer != null)timer.cancel();
timer = new Timer();
timer.schedule(databaseCheck(), 0, 5000);
}
}
private TimerTask databaseCheck() {
return new TimerTask() {
#Override
public void run() {
updateInfo();
}
};
}
private void updateInfo() {
try {
Desktop desktop = chartComp.getDesktop();
if(desktop == null) {
timer.cancel();
return;
}
Executions.activate(desktop);
try {
**<your code in here>**
} finally {
Executions.deactivate(desktop);
}
} catch (DesktopUnavailableException ex) {
System.out.println("Desktop currently unavailable");
timer.cancel();
} catch (InterruptedException e) {
System.out.println("The server push thread interrupted");
timer.cancel();
}
}

Show previous instance of RCP application

I had an rcp application which runs for only first run, when a user attempts to re-execute the application, second instance behaves as a client which encodes and sends its arguments over the socket to the first instance which acts as a server and then exits silently. The first instance receives and decodes that message, then behaves as if it had been invoked with those arguments.
so far so good i made internal protocol specification for passing arguments between two instances.
I could not bring the first instance(RCP application) to front. It is in minimized state only,
this is in continuation to my previous question
the change i made to previous post is start method of application class
public Object start(IApplicationContext context) throws Exception {
if (!ApplicationInstanceManager.registerInstance()) {
return IApplication.EXIT_OK;
}
ApplicationInstanceManager
.setApplicationInstanceListener(new ApplicationInstanceListener() {
public void newInstanceCreated() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
System.out.println("New instance detected...");
//Display.getCurrent().getActiveShell()
.forceActive();// this gives null
// pointer exception
// hence commented
}
});
}
});
Display display = PlatformUI.createDisplay();
try {
int returnCode = PlatformUI.createAndRunWorkbench(display,
new ApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART)
return IApplication.EXIT_RESTART;
else
return IApplication.EXIT_OK;
} finally {
display.dispose();
}
}
below line is stopping me to bring Application to front
Display.getCurrent().getActiveShell().forceActive();
generates null pointer exception at getActiveShell()
how can i maximize the previous instance or bring it to front
I wrote an instance manager to restrict my RCP to a single instance.
Here's the code that goes in Application.java, in the start method:
if (!ApplicationInstanceManager.registerInstance()) {
return IApplication.EXIT_OK;
}
ApplicationInstanceManager
.setApplicationInstanceListener(new ApplicationInstanceListener() {
public void newInstanceCreated() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (DEBUG)
System.out.println("New instance detected...");
Display.getCurrent().getActiveShell().forceActive();
}
});
}
});
Here's the listener interface:
public interface ApplicationInstanceListener {
public void newInstanceCreated();
}
And here's the Manager class:
public class ApplicationInstanceManager {
private static final boolean DEBUG = true;
private static ApplicationInstanceListener subListener;
/** Randomly chosen, but static, high socket number */
public static final int SINGLE_INSTANCE_NETWORK_SOCKET = 44331;
/** Must end with newline */
public static final String SINGLE_INSTANCE_SHARED_KEY = "$$RabidNewInstance$$\n";
/**
* Registers this instance of the application.
*
* #return true if first instance, false if not.
*/
public static boolean registerInstance() {
// returnValueOnError should be true if lenient (allows app to run on
// network error) or false if strict.
boolean returnValueOnError = true;
// try to open network socket
// if success, listen to socket for new instance message, return true
// if unable to open, connect to existing and send new instance message,
// return false
try {
final ServerSocket socket = new ServerSocket(
SINGLE_INSTANCE_NETWORK_SOCKET, 10, InetAddress
.getLocalHost());
if (DEBUG)
System.out
.println("Listening for application instances on socket "
+ SINGLE_INSTANCE_NETWORK_SOCKET);
Thread instanceListenerThread = new InstanceListenerThread(socket);
instanceListenerThread.start();
// listen
} catch (UnknownHostException e) {
EclipseLogging.logError(RabidPlugin.getDefault(),
RabidPlugin.PLUGIN_ID, e);
return returnValueOnError;
} catch (IOException e) {
return portTaken(returnValueOnError, e);
}
return true;
}
private static boolean portTaken(boolean returnValueOnError, IOException e) {
if (DEBUG)
System.out.println("Port is already taken. "
+ "Notifying first instance.");
try {
Socket clientSocket = new Socket(InetAddress.getLocalHost(),
SINGLE_INSTANCE_NETWORK_SOCKET);
OutputStream out = clientSocket.getOutputStream();
out.write(SINGLE_INSTANCE_SHARED_KEY.getBytes());
out.close();
clientSocket.close();
System.out.println("Successfully notified first instance.");
return false;
} catch (UnknownHostException e1) {
EclipseLogging.logError(RabidPlugin.getDefault(),
RabidPlugin.PLUGIN_ID, e);
return returnValueOnError;
} catch (IOException e1) {
EclipseLogging
.logError(
RabidPlugin.getDefault(),
RabidPlugin.PLUGIN_ID,
"Error connecting to local port for single instance notification",
e);
return returnValueOnError;
}
}
public static void setApplicationInstanceListener(
ApplicationInstanceListener listener) {
subListener = listener;
}
private static void fireNewInstance() {
if (subListener != null) {
subListener.newInstanceCreated();
}
}
public static void main(String[] args) {
if (!ApplicationInstanceManager.registerInstance()) {
// instance already running.
System.out.println("Another instance of this application "
+ "is already running. Exiting.");
System.exit(0);
}
ApplicationInstanceManager
.setApplicationInstanceListener(new ApplicationInstanceListener() {
public void newInstanceCreated() {
System.out.println("New instance detected...");
// this is where your handler code goes...
}
});
}
public static class InstanceListenerThread extends Thread {
private ServerSocket socket;
public InstanceListenerThread(ServerSocket socket) {
this.socket = socket;
}
#Override
public void run() {
boolean socketClosed = false;
while (!socketClosed) {
if (socket.isClosed()) {
socketClosed = true;
} else {
try {
Socket client = socket.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
String message = in.readLine();
if (SINGLE_INSTANCE_SHARED_KEY.trim().equals(
message.trim())) {
if (DEBUG)
System.out.println("Shared key matched - "
+ "new application instance found");
fireNewInstance();
}
in.close();
client.close();
} catch (IOException e) {
socketClosed = true;
}
}
}
}
}
}
After your IApplication start up, you can also check and lock the OSGi instance location using org.eclipse.osgi.service.datalocation.Location.isSet() and org.eclipse.osgi.service.datalocation.Location.lock()
The location is usually retrieved from your Activator using code like:
public Location getInstanceLocation() {
if (locationTracker == null) {
Filter filter = null;
try {
filter = context.createFilter(Location.INSTANCE_FILTER);
} catch (InvalidSyntaxException e) {
// ignore this. It should never happen as we have tested the
// above format.
}
locationTracker = new ServiceTracker(context, filter, null);
locationTracker.open();
}
return (Location) locationTracker.getService();
}