Wednesday, October 17, 2018

react-native-background-geolocation not giving exact location while app is in background

Leave a Comment

I have used mauron85/react-native-background-geolocation for tracking the location of the user on my react native app. It is working fine while the app is on fore ground. The location is exact on regular interval. But if the app goes to background, the location is not the same, rather is moved from the previous location even though the device is not moved. Following is my configuration -

BackgroundGeolocation.configure({     desiredAccuracy: BackgroundGeolocation.HIGH_ACCURACY,     notificationTitle: 'Background tracking',     notificationText: 'enabled',     debug: false,     startOnBoot: false,     stopOnTerminate: false,     locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,     interval: 40000,     fastestInterval: 5000,     activitiesInterval: 10000,     stopOnStillActivity: false,     url: 'http://192.168.81.15:3000/location',     httpHeaders: {         'X-FOO': 'bar'     },     // customize post properties     postTemplate: {         lat: '@latitude',         lon: '@longitude',         foo: 'bar' // you can also add your own properties     } }); 

What should I do to fix this issue?

1 Answers

Answers 1

According the documentation, the location provider you are using BackgroundGeolocation.ACTIVITY_PROVIDER is better suited as a foreground location provider:

ACTIVITY_PROVIDER:

This one is best to use as foreground location provider (but works in background as well). It uses Android FusedLocationProviderApi and ActivityRecognitionApi for maximum battery saving.

So I would try to use DISTANCE_FILTER_PROVIDER instead:

BackgroundGeolocation.configure({      locationProvider: BackgroundGeolocation.DISTANCE_FILTER_PROVIDER }); 

This provider seems to be better suited to be used as a background location provider:

DISTANCE_FILTER_PROVIDER

It's best to use this one as background location provider. It is using Stationary API and elastic distance filter to achieve optimal battery and data usage.

Source:

https://github.com/mauron85/react-native-background-geolocation/blob/master/PROVIDERS.md

Read More

Rails Devise API - Login route responds with `You need to sign in or sign up before continuing.`

1 comment

I'm currently using Devise with my Rails API app to authenticate users using devise-jwt.

This is what my User model looks like:

class User < ApplicationRecord   devise :database_authenticatable,          :registerable,          :jwt_authenticatable,          jwt_revocation_strategy: JWTBlackList end 

And config/routes.rb is set up like this:

Rails.application.routes.draw do   devise_for :users,          path: '',          path_names: {            sign_in: 'login',            sign_out: 'logout',            registration: 'signup'          },          controllers: {            sessions: 'sessions',            registrations: 'registrations'          } end 

This is the sessions controller:

class SessionsController < Devise::SessionsController    private    def respond_with(resource, _opts = {})     render json: resource   end    def response_to_on_destroy     head :no_content   end end 

and the registrations controller:

class RegistrationsController < Devise::RegistrationsController   respond_to :json    def create     build_resource(sign_up_params)      resource.save     render_resource(resource)   end end 

I ran some Rspec tests shown below which were successful -

require 'rails_helper'  RSpec.describe SessionsController, type: :request do   let(:user) { create(:user) }   let(:url) { '/login' }   let(:params) do     {       user: {         email: user.email,         password: user.password       }     }   end    context 'when params are correct' do     before do       post url, params: params     end      it 'returns 200' do       expect(response).to have_http_status(200)     end      it 'returns JTW token in authorization header' do       expect(response.headers['Authorization']).to be_present     end      it 'returns valid JWT token' do       decoded_token = decoded_jwt_token_from_response(response)       expect(decoded_token.first['sub']).to be_present     end   end end 

But when I run the following POST request to /login on Postman I get the following message:

postman request

On the right hand side you are able to see the rails console and server, showing the credentials are correct, but still we get 401

Any clues on what might be wrong? It's been difficult finding good resources on Devise using Rails API.

Thank you in advance

1 Answers

Answers 1

After digging through the SessionsController I found the reason it returned 401: warden was trying to authenticate an empty body. Fixed this by added Content-Type to the request header

Read More

Calling multiple methods with same name using SoapClient

Leave a Comment

I have a SOAP webservice and in SOAP UI I see that there are methods with the same name. So, for example, there are 2 CreateNewContact methods, one of which takes 3 parameters and the other 4. Below are the stubs generated by SOAP UI

Method 1 Stub:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rfp="http://test.com/testWebservice/">    <soapenv:Header/>    <soapenv:Body>       <rfp:CreateNewContact_FullName>          <!--Optional:-->          <rfp:fullName>?</rfp:fullName>          <!--Optional:-->          <rfp:email>?</rfp:email>          <!--Optional:-->          <rfp:telNo>?</rfp:telNo>       </rfp:CreateNewContact_FullName>    </soapenv:Body> </soapenv:Envelope> 

Method 2 Stub:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rfp="http://test.com/testWebservice/">    <soapenv:Header/>    <soapenv:Body>       <rfp:CreateNewContact_FirstLastName>          <!--Optional:-->          <rfp:firstName>?</rfp:firstName>          <!--Optional:-->          <rfp:lastName>?</rfp:lastName>          <!--Optional:-->          <rfp:email>?</rfp:email>          <!--Optional:-->          <rfp:telNo>?</rfp:telNo>       </rfp:CreateNewContact_FirstLastName>    </soapenv:Body> </soapenv:Envelope> 

When I call the CreateNewContact method with 4 parameters using PHP SoapClient, it looks like I'm getting the response from the other method.

How can I specify which method to use using SoapClient?

Thanks,

2 Answers

Answers 1

As you can read here:

If you are using WSDL based SOAP requests and you have more than one operation in your binding (with the same parameters), make sure the style is set to rpc, NOT body! When you specify 'body' here, all that will be transmitted in the request is the parameters for the function call, and SoapServer->handle() will use the first function it finds with the same parameter-makeup to handle the call. The actual method to call will only be included in the request when your type is set to 'rpc', resulting in the expected behavior

Therefore, you should check in your WSDL the operation element, which provides binding information from the abstract operation to the concrete SOAP operation.
For example:

<definitions ....>;     <binding .... >;         <operation .... >;            <soap12:operation soapAction="xs:anyURI" ?                               soapActionRequired="xs:boolean" ?                               style="rpc|document" ?                               wsdl:required="xs:boolean" ? /> ?         </soap12:operation>     </binding>; </definitions> 

The style attribute value, if present, is a string that specifies the style for the operation. The style attribute indicates whether the operation is RPC-oriented (a messages containing parameters and return values) or document-oriented (a message containing documents). If the style attribute is omitted from the soap12:operation element, then the operation inherits the style specified or implied by the soap12:binding element in the containing wsdl:binding element.
So, in short, to solve your problem you should change the operation style from "document" to "rpc" in your WSDL.
As a further reference: https://bugs.php.net/bug.php?id=49169

Answers 2

I have faced the same with travelport universal API, I ended up modifying my local wsdl file to use different name for each method and it worked perfectly.

Read More

Android location manager error 'Exiting with error onLocationChanged line 152 “1”'

1 comment

I have a location manager in my Android app that sometimes works. Sometimes I'll run the app and it will get location updates (with some errors). Sometimes I'll run it and it will just throw this error every couple seconds without receiving any location updates:

E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1" 

Here is my class for managing location events:

package com.company.AppName;  import android.app.job.JobParameters; import android.app.job.JobService; import android.content.Context; import android.content.Intent; import android.location.Criteria; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.util.Log;  public class LocationListenerService extends JobService {   private static final String TAG = "LocationListenerService";   private LocationManager locationManager = null;   private LocationListener locationListener = null;   private String locationProvider = null;    public LocationListenerService() {}    @Override   public int onStartCommand(Intent intent, int flags, int startId) {     return START_STICKY;   }    @Override   public boolean onStartJob(JobParameters params) {     Log.i(TAG, "onStartJob");     startLocationManager(params);     return true;   }    @Override   public boolean onStopJob(JobParameters params) {     Log.i(TAG, "onStopJob");     return false;   }    public void startLocationManager(JobParameters params) {     if(locationManager != null) return;      Criteria criteria = new Criteria();     criteria.setAccuracy(Criteria.ACCURACY_FINE);   //    criteria.setPowerRequirement(Criteria.POWER_LOW);     criteria.setAltitudeRequired(false);     criteria.setBearingRequired(false);      locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);     locationProvider = locationManager.getBestProvider(criteria, true);     locationListener = new LocationListener();      if (locationProvider != null) {       Log.v(TAG, "Location provider: " + locationProvider);     } else {       Log.e(TAG, "Location provider is null. Location events will not work.");       return;     }      if (locationListener == null) {       Log.e(TAG, "Location listener is null. Location events will not work.");       return;     }      // Finish job after first time updating location with the server     NativeApp.shared().getLocationData((NativeApp app, String response) -> {       Log.i(TAG, "Received location data response. Finishing job.");       jobFinished(params, true);     });      try {       locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);     } catch (java.lang.SecurityException ex) {       Log.e(TAG, "fail to request location update, ignore", ex);     } catch (IllegalArgumentException ex) {       Log.e(TAG, "network provider does not exist, " + ex.getMessage());     }   }    private class LocationListener implements android.location.LocationListener {     @Override     public void onLocationChanged(Location location) {       if(location == null) {         Log.w(TAG, "onLocationChanged skipped: null location");         return;       }       Log.i(TAG, "onLocationChanged: " + location.toString());       NativeApp.shared().updateLocation(location);     }      @Override     public void onProviderDisabled(String provider) {       Log.i(TAG, "onProviderDisabled: " + provider);     }      @Override     public void onProviderEnabled(String provider) {       Log.i(TAG, "onProviderEnabled: " + provider);     }      @Override     public void onStatusChanged(String provider, int status, Bundle extras) {       Log.i(TAG, "onStatusChanged: " + provider);     }   } } 

Why is this happening? Why do location updates work sometimes but not other times?

EDIT: After giving up for a few hours and rerunning, the app is still throwing the error repeatedly, but after about 10 seconds logs this and starts receiving location updates:

E/XTCC-6.1.2.10: [FDAL_OSListener] handleLocationUpdate:  failed: 2 D/LocationManagerService: incoming location: gps I/LgeGnssLocationProvider: Intent - android.location.GPS_FIX_CHANGE D/LgeGnssLocationProvider: GPS_FIX_CHANGE_ACTION! , mGpsNavigating =true D/LocationManagerService: incoming location: gps 

2 Answers

Answers 1

long milliseconds = 5000; // 5 seconds float minimusDistance = 5.5; // 5.5m distance from current location locationManager.requestLocationUpdates(locationProvider, milliseconds, minimusDistance, locationListener); 

Try this snippet. Hope it will solve your problem.

This is happening only, for this reason, you're not providing a minimum interval and minimum distance to get location updates. That's why you're getting this error.

Here is the link check it out - requestLocationUpdates

Answers 2

This location update gets varies as per the android version. Recently Android introduce background location limits in oreo which says:

While your app is in the foreground, you should receive location updates as frequently as you requested. When your app goes in the background, your app will receive location updates only a few times each hour (the location update interval may be adjusted in the future based on system impact and feedback from developers).

Android recommend to use fused location APIs for below reason, you must consider it for your scenario which says:

If your app needs access to location history that contains time-frequent updates, use the batched version of the Fused Location Provider API elements, such as the FusedLocationProviderApi interface. When your app is running in the background, this API receives the user's location more frequently than the non-batched API. Keep in mind, however, that your app still receives updates in batches only a few times each hour.

Please refer below links for and better approach:

https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService/app

https://codelabs.developers.google.com/codelabs/background-location-updates-android-o/index.html#0

Note: The "O" background location limits only kick in when your app is no longer in the foreground.

Please let me know if above two links not working for you.

Read More

Move IIS Logs to AWS s3 bucket

Leave a Comment

I have a requirement to upload IIS logs 7 days older to AWS S3 Bukcet. By using below code I am able to access AWS folders under bucket

Import-Module "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSPowerShell.psd1" $AKey = "" $SKey = "" $source = "C:\inetpub\logs\LogFiles\*" $outputpath = "C:\scripts\Logs\logs3.txt" Set-AWSCredentials -AccessKey $AKey -SecretKey $SKey  function Get-Subdirectories {     param  (         [string] $BucketName,         [string] $KeyPrefix,         [bool] $Recurse     )      @(Get-S3Object -BucketName $BucketName -KeyPrefix $KeyPrefix -Delimiter '/') | Out-Null      if ($AWSHistory.LastCommand.Responses.Last.CommonPrefixes.Count -eq 0) {         return     }      $AWSHistory.LastCommand.Responses.Last.CommonPrefixes      if ($Recurse) {         $AWSHistory.LastCommand.Responses.Last.CommonPrefixes | ForEach-Object { Get-Subdirectories -BucketName $BucketName -KeyPrefix $_ -Recurse $Recurse }     } }  function Get-S3Directories {     param  (         [string] $BucketName,         [bool] $Recurse = $false     )     Get-Subdirectories -BucketName $BucketName -KeyPrefix '/' -Recurse $Recurse  } 

Now if I type Get-S3Directories -BucketName backups I get the following output:

SERVER-xxx-OLogs/ SERVER-xxx-untime-logs / SERVER-xxx-FRLogs/ SERVER-oooooRLogs/ SERVER-IISLogFiles/ 

Now the challenge is I have to move IIS older than 7 days under SERVER-IISLogFiles/ Directory

So I have created this

$sfolder = Get-S3Directories -BucketName Backups Foreach ($folder in $sfolder) {     $wc = New-Object System.Net.WebClient      Set-AWSCredentials -AccessKey $AKey -SecretKey $SKey -StoreAs For_Move     Initialize-AWSDefaults -ProfileName For_Move -Region US-east-1      Start-Transcript -path $outputpath -Force     foreach ($i in Get-ChildItem $source -include *.log -recurse) {         if ($i.CreationTime -lt ($(Get-Date).AddDays(-7))) {             $fileName = (Get-ChildItem $i).Name             $parentFolderName = Split-Path (Split-Path $i -Parent) -Leaf             Write-S3Object -BucketName $folder -File $i         }     } } Stop-Transcript 

I am not entirely sure whether its going to move to SERVER-IISLogFiles/ Directory, not sure if I am missing anything here apart from this, I doubt its going to keep the folder structure of local IIS folder on IIS

1 Answers

Answers 1

UPDATE:

You could try and use the following method to create your folder structure within you S3 Bucket. Using the Key Prefix parameter and splitting your path to your folders should work.

$Params = @{     BucketName = 'backup'     Folder = '$Source or whatever path'     KeyPrefix = (Split-Path -Path 'C:\PATHTO\SOURCE\DIRECTORY' -Leaf).TrimEnd('\')     Recurse = $true     Region = 'REGION' } Write-S3Object @Params 
Read More

Tuesday, October 16, 2018

Hide Navigation Controller Search Bar & opened Large Title programmatically

Leave a Comment

I have a tableView. I set the all settings about searchController ( Search Bar in Large Navigation Bar ) - ( open / close when scroll tableview ). I implemented rightBarButtonItem which name is 'Close' . I want to hide/close tableView and Search Bar with programmatically. I can hide tableView but not SearchBar.

When I do isHidden for SearchBar , The Large Navigation Bar doesnt shrink to normal size.

Pic 1. Opened search bar with scroll down.

enter image description here

Pic 2. Not Hidden Large Navigation Bar with programmatically ( searchar.isHidden not implemented here )

enter image description here

Thanks in advance.

I tried this before but not run

tableView.setContentOffset(.zero, animated: false) navigationController?.navigationBar.prefersLargeTitles = false 

2 Answers

Answers 1

I tried to find a proper way to hide search bar, but I didn't find. But I found a workaround to hide your search bar which is change content offset your table view.

You may try this function to hide your table view and search bar.

func hide() {     tableView.isHidden = true     let point = tableView.contentOffset     let searchBarFrame = self.navigationItem.searchController?.searchBar.frame     let newPoint = CGPoint(x: point.x, y: point.y + searchBarFrame!.height)     tableView.setContentOffset(newPoint, animated: true) } 

Answers 2

Just try this:

 navigationItem.searchController = nil 

This is all my test code:

@IBOutlet weak var tableView: UITableView!  @IBOutlet weak var leftBarButtonItem: UIBarButtonItem!  var isHidden = false  var searchController: UISearchController {      let search = UISearchController(searchResultsController: nil)      search.searchBar.placeholder = "hello world"      search.obscuresBackgroundDuringPresentation = false      return search }   override func viewDidLoad() {     super.viewDidLoad()      self.navigationItem.title = "Test"      tableView.delegate = self      tableView.dataSource = self      showSearchController() }  @IBAction func isHiddenAction(_ sender: UIBarButtonItem) {     isHidden = !isHidden      self.tableView.isHidden = isHidden      if isHidden {         leftBarButtonItem.title = "Show"         hiddenSearchController()      } else {         leftBarButtonItem.title = "Hidden"         showSearchController()     } }  func hiddenSearchController() {     navigationItem.searchController = nil }  func showSearchController() {      navigationItem.searchController = searchController      navigationItem.hidesSearchBarWhenScrolling = true      definesPresentationContext = true } 

screenShots

Read More

Django: Sessions not working as expected on Heroku

Leave a Comment

Users keep getting logged out and sessions are not persisting on my Django app on Heroku. Users can log in, but they will be randomly logged out—even on the /admin/ site.

Is there anything I'm doing wrong with my Django/Heroku config?

Currently running Django 1.11.16 on Standard Dynos.

settings.py

SECRET_KEY = os.environ.get("SECRET_KEY", "".join(random.choice(string.printable) for i in range(40)))  SESSION_COOKIE_DOMAIN = ".appname.com" CSRF_COOKIE_DOMAIN = ".appname.com"  SECURE_SSL_REDIRECT = True  # ...  MIDDLEWARE_CLASSES = [     'django.middleware.security.SecurityMiddleware',     'django.contrib.sessions.middleware.SessionMiddleware',     'django.middleware.common.CommonMiddleware',     'django.middleware.csrf.CsrfViewMiddleware',     'django.contrib.auth.middleware.AuthenticationMiddleware',     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',     'django.contrib.messages.middleware.MessageMiddleware',     'django.middleware.clickjacking.XFrameOptionsMiddleware', ]   TEMPLATES = [     {         'BACKEND': 'django.template.backends.django.DjangoTemplates',         'DIRS': [os.path.join(BASE_DIR, 'templates/')],         'APP_DIRS': True,         'OPTIONS': {             'context_processors': [                 'django.template.context_processors.debug',                 'django.template.context_processors.request',                 'django.template.context_processors.csrf',                 'django.contrib.auth.context_processors.auth',                 'django.contrib.messages.context_processors.messages',             ],         },     }, ]  # ...  DATABASES = {     'default': {         'ENGINE': 'django.db.backends.postgresql_psycopg2',         'NAME': 'appname',     } }  # https://devcenter.heroku.com/articles/python-concurrency-and-database-connections db_from_env = dj_database_url.config(conn_max_age=500) DATABASES['default'].update(db_from_env) 

1 Answers

Answers 1

The problem was that SECRET_KEY was not static on Heroku. The SECRET_KEY changing was breaking sessions. The fix is to add a static SECRET_KEY to Heroku config:

heroku config:set SECRET_KEY=`openssl rand -base64 32` 
Read More