"Cannot save a ParseUser that is not authenticated" - parse-platform

I am trying to save data in authData field android, But I am getting exception: Cannot save a ParseUser that is not authenticated" after only reading the user
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("username", email);
query.findInBackground(new FindCallback<ParseUser>() {
#SuppressWarnings("deprecation")
public void done(List<ParseUser> scoreList, ParseException e) {
if (e == null) {
if(scoreList.size()>0){
facebook_user = (ParseUser) scoreList.get(0);
facebook_user.isAuthenticated()
JSONObject obj = new JSONObject();
try {
obj.put("name", "xyz");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
facebook_user.put("authdata", obj);
facebook_user.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
// exception in this section //
//Cannot save a ParseUser that is not authenticated" after only reading the user//
});
}else{
}
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});

It looks like you are attempting to modify that user with the .put() before saving:
facebook_user.put("authdata", obj);
facebook_user.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
// exception in this section //
});
If you want to change a user, you need to be logged in as the user, execute the change on Cloud Code using the masterKey, or change the user objects' ACL. Here's a SO post with a bit more info.
Let me know if you have any more questions.

Related

Cloning javax.mail.Message and Cloning javax.mail.Multipart, Java 8

I'm implementing a mail Sender, near 1'6000.000 mails (with images and PDF) in one day per month (closing month extract), the mails are about 12 products...
I need to fill a Message Scratch per product... in order to not read (per email) else per product.
I'm trying to implement cloning javax.mail.Message and javax.mail.Multipart in order to be faster.
AddContent to Multipart
public static void addContent(final Multipart multipart, String contenidoCorreo) throws Exception {
MimeBodyPart mimeBodyPart = new PreencodedMimeBodyPart("8bit");
mimeBodyPart.setText(contenidoCorreo, "iso-8859-1", "html");
multipart.addBodyPart(mimeBodyPart, 0);
}
Add Image per Bytes
public static void addImageToMultipart(final Multipart multipart, byte[] contenidoImagen, String nombreImagen) throws Exception {
MimeBodyPart imagenMimeBodyPart = new MimeBodyPart();
try {
ByteArrayDataSource byteArrayDataSource = new ByteArrayDataSource(contenidoImagen, "image/*");
imagenMimeBodyPart.setDataHandler(new DataHandler(byteArrayDataSource));
imagenMimeBodyPart.setFileName(nombreImagen);
imagenMimeBodyPart.setContentID("<" + nombreImagen + ">");
imagenMimeBodyPart.setDisposition(MimeBodyPart.INLINE);
multipart.addBodyPart(imagenMimeBodyPart);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
AddPDF per File
public static void addPDF(final Multipart multipart, String ruta, String nombre) throws Exception {
Path path = Paths.get(ruta, nombre);
if (path.toFile().exists()) {
MimeBodyPart preencodedMimeBodyPart = new PreencodedMimeBodyPart("base64");
preencodedMimeBodyPart.attachFile(path.toFile());
preencodedMimeBodyPart.setFileName(nombre);
preencodedMimeBodyPart.setHeader("Content-Type", "application/pdf");
preencodedMimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
multipart.addBodyPart(preencodedMimeBodyPart);
MimeBodyPart pdfMimeBodyPart = new MimeBodyPart();
}
My Cloning Message
public static Message cloneMessage(Message source) {
//Multiple and Separated Exceptions because maybe not all properties are defined in some time.
Message target = new MimeMessage(source.getSession());
try {
if (source.getFrom() != null && source.getFrom().length > 0) {
Address address = (source.getFrom()[0]);
target.setFrom(new InternetAddress(((InternetAddress) address).getAddress(), ((InternetAddress) address).getPersonal()));
}
} catch (Exception ex) {
//Handle Exception
}
try {
target.setSentDate((Date) (source.getSentDate().clone()));
} catch (MessagingException ex) {
//Handle Exception
}
try {
target.setRecipients(Message.RecipientType.TO, target.getRecipients(Message.RecipientType.TO).clone());
} catch (MessagingException ex) {
//Handle Exception
}
try {
Enumeration numerationHeaders = source.getAllHeaders();
while (numerationHeaders.hasMoreElements()) {
Header header = (Header) numerationHeaders.nextElement();
target.addHeader(header.getName(), header.getValue());
}
} catch (MessagingException ex) {
//Handle Exception
}
try {
target.setSubject(new String(source.getSubject()));
} catch (MessagingException ex) {
//Handle Exception
}
try {
target.setContent(cloneMultipart((Multipart)(source.getContent())));
} catch (Exception ex) {
//Handle Exception
}
return target;
}
Cloning Multipart
public static Multipart cloneMultipart(Multipart source) {
MimeMultipart target = new MimeMultipart();
try {
for (int i = 0; i < source.getCount(); i++) {
MimeBodyPart mimeBodyPart = (MimeBodyPart)source.getBodyPart(i);
mimeBodyPart //?????
}
} catch (MessagingException ex) {
//Handle Exception
}
return target;
}
How cloning Multipart?
some advice to clone Message?
How detect the Content (the used with addContent method) has been added?

Updating value in parse table

I am using parse.com cloud in my android application. i want to increase a field by one
I tried using three ways.
first i tried getting object using parseQuery.get(id) but it gives no object found for update after using parseObject.increament().
ParseQuery<ParseObject> parseQuery = ParseQuery.getQuery("Waive");
try {
ParseObject object=parseQuery.get(id);
object.increment("numberOfViews");
object.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException arg0) {
// TODO Auto-generated method stub
if(arg0==null){
Log.e("incremented", "by one");
}
else{
Log.e("not incremented", "by one");
arg0.printStackTrace();
}
}
});
} catch (ParseException e) {
// TODO Auto-generated catch block
Log.e("exception", e+"");
e.printStackTrace();
}
second way i used.i tried using ParseObject.increament but it gives no object found for update.
ParseQuery< ParseObject> query=new ParseQuery<ParseObject>("Waive");
query.getInBackground(id, new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
// TODO Auto-generated method stub
Log.e("object id", object+"");
if(e==null && object!=null){
object.increment("numberOfViews");
try {
object.save();
} catch (ParseException exp) {
// TODO Auto-generated catch block
Log.e("exception", exp.getMessage());
exp.printStackTrace();
}
}
}
});
}
third way i tried ,first of all i get the value of that field then increamented that value by one and inserted that value in table by using parseObject.put
ParseQuery< ParseObject> query=new ParseQuery("Waive");
query.getInBackground(id, new GetCallback() {
#Override
public void done(ParseObject object, ParseException e) {
// TODO Auto-generated method stub
Log.e("object id", object+"");
if(e==null && object!=null){
int tmp=(Integer)object.getNumber("numberOfViews");
object.put("numberOfViews", tmp+1);
try {
object.save();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
Log.e("exception", e1.getMessage());
e1.printStackTrace();
}
}
}
});
}
but neither of these three is working please help me out.
It is due to the permission issues. Because you are trying to update a value you are not authorized for. Make it public by editing your table security on parse.com make it public writable to update by another user too

Adobe CQ : Regarding Session in Event Listener

I have a question regarding event listener. We have a event listener which listen to delete node event and perform some activity say "send email".
While code review i found this, although this code is working fine i am not convinced with the session being handled here :
#Activate
protected void activate(ComponentContext context) {
try{
final String path="/content/dam/";
Session session = repository.loginAdministrative(repository.getDefaultWorkspace());
observationManager = session.getWorkspace().getObservationManager();
observationManager.addEventListener(this, Event.PROPERTY_REMOVED, path, true, null, null, true);
checkOutProperty = OsgiUtil.toString(context.getProperties()
.get(ASSET_LOCK_PROPNAME_UPDATE), ASSET_LOCK_PROPNAME_DEFAULT);
if (session != null && session.isLive()) {
session.save();
}
} catch (RepositoryException e) {
if(LOG.isErrorEnabled()){
LOG.error("Error Occured in activate method of Property Removed Listener class:" + e.getMessage());
}
}catch (Exception e) {
if(LOG.isErrorEnabled()){
LOG.error("Error Occured in activate method of Property Removed Listener class:"+e.getMessage());
}
}
}
#Deactivate
protected void deactivate(ComponentContext componentContext) {
try {
if (observationManager != null) {
observationManager.removeEventListener(this);
}
} catch (RepositoryException e) {
if(LOG.isErrorEnabled()){
LOG.error("Error Occured " + e);
}
} catch (Exception e) {
if(LOG.isErrorEnabled()){
LOG.error(e.getMessage());
}
}
}
Questions:
Best practice would be to create session object private to this class and should be logout in deactivate method?
Once an event is added in Observation Manager, do we really need session object? I was expecting if we should logout from session there.
EventListener are a bit cumbersome here. I fought many battles with JCR Sessions and Sling ResourceResolvers within them. The problem is, you need to keep the Session active as long as the Event Listener is active. So the only thing missing in your code is a logout on deactivate.
I created an AbstractEventListener which takes care of this and provides the following two methods and has two private members:
private Session session;
private ObservationManager observationManager;
protected void addEventListener(final EventListener eventListener,
final int eventTypes, final String path, final String[] nodeTypes) {
try {
session = getRepositorySession();
observationManager = session.getWorkspace().getObservationManager();
observationManager.addEventListener(eventListener, eventTypes,
path, true, null, nodeTypes, true);
} catch (RepositoryException e) {
LOGGER.error("Repository error while registering observation: ", e);
}
}
protected void removeEventListener(final EventListener eventListener) {
if (observationManager != null) {
try {
observationManager.removeEventListener(eventListener);
} catch (RepositoryException e) {
LOGGER.error(
"Repository error while unregistering observation: ", e);
} finally {
logoutSession(session);
}
}
}
And then in the actual EventListener I just call them:
protected void activate(ComponentContext context) {
addEventListener(this, Event.PROPERTY_ADDED| Event.PROPERTY_CHANGED, "/content/mysite", null);
}
}
protected void deactivate(ComponentContext componentContext) {
removeEventListener(this);
}

How to update volume bar in MinimalMediaRouteProvider

I am using registerMediaRouteProvider and it gives you a volume bar to update the tv's volume. I implemented MediaRouteAdapter and when I scrub the volume bar, the volume changes, but the volume bar's ui always resets back to 0. How do I update the ui of the volume bar when the volume changes?
#Override
public void onCreate(Bundle savedInstanceState) {
mCastContext = new CastContext(getApplicationContext());
MediaRouteHelper.registerMinimalMediaRouteProvider(mCastContext, this);
mMediaRouter = MediaRouter.getInstance(getApplicationContext());
mMediaRouteSelector = MediaRouteHelper.buildMediaRouteSelector(MediaRouteHelper.CATEGORY_CAST);
mMetaData = new ContentMetadata();
mMediaRouterCallback = new MyMediaRouterCallback();
mMediaRouteButton.setRouteSelector(mMediaRouteSelector);
}
private class MyMediaRouterCallback extends MediaRouter.Callback {
#Override
public void onRouteSelected(MediaRouter router, RouteInfo route) {
MediaRouteHelper.requestCastDeviceForRoute(route);
}
#Override
public void onRouteUnselected(MediaRouter router, RouteInfo route) {
try {
if (mSession != null) {
Log.e(TAG, "Ending session and stopping application");
mSession.setStopApplicationWhenEnding(true);
mSession.endSession();
} else {
Log.e(TAG, "onRouteUnselected: mSession is null");
}
} catch (IllegalStateException e) {
Log.e(TAG, "onRouteUnselected:");
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG, "onRouteUnselected:");
e.printStackTrace();
}
mSelectedDevice = null;
}
}
#Override
public void onDeviceAvailable(CastDevice device, String arg1, MediaRouteStateChangeListener listener) {
mSelectedDevice = device;
openSession();
}
#Override
public void onSetVolume(double volume) {
try {
if (mMessageStream != null) {
mMessageStream.setVolume(volume);
}
} catch (IllegalStateException e) {
Log.e(TAG, "Problem sending Set Volume", e);
} catch (IOException e) {
Log.e(TAG, "Problem sending Set Volume", e);
}
}
#Override
public void onUpdateVolume(double volumeChange) {
try {
if (mCurrentRoute != null) {
mCurrentRoute.requestUpdateVolume((int) (volumeChange * 20));
}
} catch (IllegalStateException e) {
Log.e(TAG, "Problem sending Update Volume", e);
}
}
EDIT - added where I initialize mMessageStream
private void openSession() {
mSession = new ApplicationSession(mCastContext, mSelectedDevice);
int flags = 0;
flags |= ApplicationSession.FLAG_DISABLE_NOTIFICATION;
flags |= ApplicationSession.FLAG_DISABLE_LOCK_SCREEN_REMOTE_CONTROL;
mSession.setApplicationOptions(flags);
Log.d(TAG, "Beginning session with context: " + mCastContext);
Log.d(TAG, "The session to begin: " + mSession);
mSession.setListener(new com.google.cast.ApplicationSession.Listener() {
#Override
public void onSessionStarted(ApplicationMetadata appMetadata) {
Log.d(TAG, "Getting channel after session start");
ApplicationChannel channel = mSession.getChannel();
if (channel == null) {
Log.e(TAG, "channel = null");
return;
}
Log.d(TAG, "Creating and attaching Message Stream");
mMessageStream = new MediaProtocolMessageStream();
channel.attachMessageStream(mMessageStream);
if (mMessageStream.getPlayerState() == null) {
if (vastVideoView.getPlayingPlaylistItem() != null) {
loadMedia();
}
} else {
Log.e(TAG, "Found player already running; updating status");
}
}
#Override
public void onSessionStartFailed(SessionError error) {
Log.e(TAG, "onStartFailed " + error + " code " + error.getCode());
nowifi.setVisibility(View.GONE);
}
#Override
public void onSessionEnded(SessionError error) {
Log.i(TAG, "onEnded " + error);
controller.removeChromeCastListener();
controller.setChromeCast(false);
nowifi.setVisibility(View.GONE);
}
});
try {
Log.e(TAG, "Starting session with app name " + getString(R.string.app_id));
mSession.startSession(getString(R.string.app_id));
vastVideoView.stopPlayback();
controller = vastVideoView.getMediaController();
controller.setChromeCast(true);
controller.setPausePlayListener(pausePlayListener);
seekBar = controller.getSeekBar();
seekBar.setProgress(0);
mPlayButtonShowsPlay = true;
} catch (IOException e) {
Log.e(TAG, "Failed to open session", e);
controller.removeChromeCastListener();
controller.setChromeCast(false);
nowifi.setVisibility(View.GONE);
}
}
I've been looking for this for days and I suddenly found the solution by myself :P
First, You will need a MediaRouteStateChangeListener to handle this.
MediaRouteStateChangeListener mRouteStateListener;
Second, assign the listener in onDeviceAvailable.
#Override
public void onDeviceAvailable(CastDevice device, String arg1, MediaRouteStateChangeListener listener) {
mSelectedDevice = device;
mRouteStateListener = listener;
openSession();
}
Last, call MediaRouteStateListener.onVolumeChanged() in onSetVolume or onUpdateVolume.
#Override
public void onSetVolume(double volume) {
try {
if (mMessageStream != null) {
mMessageStream.setVolume(volume);
mRouteStateListener.onVolumeChanged(volume);
}
} catch (IllegalStateException e) {
Log.e(TAG, "Problem sending Set Volume", e);
} catch (IOException e) {
Log.e(TAG, "Problem sending Set Volume", e);
}
}
This should help your volume seekbar to act normally. :)
At the Receiver level, there are two ways to set the volume:
cast.Receiver.Platform.setVolume([0.0,1.0])
This will set the volume and show the blue bar. This is what is usually called by the onVolume message.
mediaElement.volume = [0.0, 1.0];
This will set the volume without showing the blue bar. You can use this for fade in / fade out, and for equalization.
Now on to your Java code:
I don't see how you are getting your messageStream in what you've posted, but since it's likely to be the right thing. Here's the lines from the reference docs:
public final MediaProtocolCommand setVolume (double volume)
Sets the audio volume.
Parameters
volume The volume, in the range 0.0 (0%) to 1.0 (100%).
Returns
The command object for this request
Throws
IOException If an I/O error occurs while sending the message.
IllegalStateException If this stream is not attached to a connected channel.
Google updated volume controls this summer so they are shared between connected devices and apps. Please see my solution here:
https://stackoverflow.com/a/26554007/672373

Posting HTTPS form results in html 404 status code

I keep getting a HTML 404 reply from the server when I try to login via a httppost (https). Not sure if this is a cookie problem or something else. The code should be good as I have copied it from another activity. I need some help.
This is my current code:
public int postData(String usernamne, String password) {
String url = "https://domainname.com/nclogin.submit";
HttpPost httppost = new HttpPost(url);
try {
KeyStore trusted = null;
try {
trusted = KeyStore.getInstance("BKS");
} catch (KeyStoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
trusted.load(null, "".toCharArray());
MySSLSocketFactory sslf = null;
try {
sslf = new MySSLSocketFactory(trusted);
} catch (KeyManagementException e) {
Log.d(TAG, "Exception " + e);
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
Log.d(TAG, "Exception " + e);
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyStoreException e) {
Log.d(TAG, "Exception " + e);
// TODO Auto-generated catch block
e.printStackTrace();
}
sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("f_username", "myemail#address.com"));
nameValuePairs.add(new BasicNameValuePair("f_passwd", "mypassword"));
nameValuePairs.add(new BasicNameValuePair("f_method", "LOGIN"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", sslf, 443));
SingleClientConnManager cm = new SingleClientConnManager(httppost.getParams(), schemeRegistry);
// NEW API WONT ALLOW THIS IN THE MAIN THREAD! hence ASYNC
DefaultHttpClient client = new DefaultHttpClient(cm, httppost.getParams());
HttpResponse result = client.execute(httppost);
// Check if server response is valid
StatusLine status = result.getStatusLine();
Log.d(TAG, "STatus" + result.getStatusLine());
if (status.getStatusCode() != 200) {
throw new IOException("Invalid response from server: " + status.toString());
}
HttpEntity entity = result.getEntity();
InputStream is = entity.getContent();
if (is != null) {
is.close(); // release connection
}
String phpsessid = "";
// cookies from another blog
// http://stackoverflow.com/questions/4224913/android-session-management
List cookies = client.getCookieStore().getCookies();
if (cookies.isEmpty()) {
Log.d(TAG, "no cookies received");
} else {
for (int i = 0; i < cookies.size(); i++) {
// Log.d(TAG, "COOKIE-" + i + " " +
// cookies.get(i).toString());
if (cookies.get(i).toString().contains("PHPSESSID")) {
phpsessid = cookies.get(i).toString();
Log.d(TAG, "COOKIE FOR PHPSESSID - " + phpsessid);
}
}
} // end of blog
entity.consumeContent();
client.getConnectionManager().shutdown();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (CertificateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return 1;
} // end of postData()
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
#Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host,
port, autoClose);
}
#Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
I know the url is correct, as are the name value pairs, as I can login via a query string via a browser or via wget:
https://domainname.com/nclogin.submit?f_username=myemail#email.com&f_passwd=password&f_method=LOGIN
This results in a connection established and a redirect to my dashboard page.
The HTML code (source) from the login page can be viewed
here

Resources