I've found that the FCM web client side occasionally delivers a different token to me.
My code is entirely based on the official docs.
// Get registration token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken({ vapidKey: '<YOUR_PUBLIC_VAPID_KEY_HERE>' }).then((currentToken) => {
if (currentToken) {
// Send the token to your server and update the UI if necessary
// Occasionally, I received a different token here.
} else {
// Show permission request UI
console.log('No registration token available. Request permission to generate one.');
// ...
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// ...
});
Occasionally, I receive a different currentToken; this occurs regularly!
I did not change my web browser (Chrome), nor did I change the vapidKey, and I continue to use the same tab for localhost development.
It seemed to have changed every couple of hours.
And if the token changes, my service worker will record an error in the console, as well as a 404 API request failure.
The console log error is as follows:
FirebaseError: Messaging: A problem occurred while unsubscribing the user from FCM: FirebaseError: Messaging: A problem occurred while unsubscribing the user from FCM: Requested entity was not found. (messaging/token-unsubscribe-failed). (messaging/token-unsubscribe-failed).
at _callee8$ (eval at <anonymous> (app.js:2982), <anonymous>:572:45)
at tryCatch (eval at <anonymous> (app.js:6025), <anonymous>:62:40)
at Generator.invoke [as _invoke] (eval at <anonymous> (app.js:6025), <anonymous>:296:22)
at Generator.prototype.<computed> [as next] (eval at <anonymous> (app.js:6025), <anonymous>:114:21)
at step (eval at <anonymous> (app.js:636), <anonymous>:17:30)
at eval (eval at <anonymous> (app.js:636), <anonymous>:28:13)
And here is the failed API request I believe FCM was attempting to make; I did not make the request, and I copied it as curl for greater visibility.
curl 'https://fcmregistrations.googleapis.com/v1/projects/chatisfy-d2721/registrations/cD0VOZLBLdaVymfaUbQyE4:APA91bHj2qCU02_Sib6gEPw3VuPTDkjpj0ZVpgmWYaaHESpTjpH-uwY5JX5mn_W7YhJ1AOMp4dNnwpUffs7SQkBs1UYGGie0o4u_i-OjYY5Q5uRSl3pZQoRGVzwNXxe0lDrQIHD4SN5A' \
-X 'DELETE' \
-H 'authority: fcmregistrations.googleapis.com' \
-H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' \
-H 'content-type: application/json' \
-H 'accept: application/json' \
-H 'x-goog-api-key: AIzaSyDFP12b-P9JwiDvJuqsWVz6k2Z8ww6_2-E' \
-H 'x-goog-firebase-installations-auth: FIS eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6IjE6NTI4MTcxMTk2MzYxOndlYjowMWQyMzQ4ODNiYWQ3NWU5MmYxMjE4IiwiZXhwIjoxNjQwMjUwMDc2LCJmaWQiOiJjRDBWT1pMQkxkYVZ5bWZhVWJReUU0IiwicHJvamVjdE51bWJlciI6NTI4MTcxMTk2MzYxfQ.AB2LPV8wRQIhAL4F96JV_fSn2LHzpBiYDWnOVcpA7zBT35lvWz0WqS8fAiAlC28Un0hO2uD6_DuRPnHdqnO_5wIr-byID127niFXRg' \
-H 'sec-ch-ua-platform: "macOS"' \
-H 'origin: http://localhost:8080' \
-H 'x-client-data: CJO2yQEIpbbJAQjBtskBCKmdygEInvnLAQjmhMwBCLWFzAEIy4nMAQjSj8wBGI6eywE=' \
-H 'sec-fetch-site: cross-site' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-dest: empty' \
-H 'referer: http://localhost:8080/' \
-H 'accept-language: en-US,en;q=0.9,zh-TW;q=0.8,zh;q=0.7,zh-CN;q=0.6' \
--compressed
And here is the response to the aforementioned request:
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
What is causing this?
Some security models expire and reissue tokens at intervals to prevent long-term token validity. Or the token may contain data that updates based on request time.
I'm trying to increment the output of a zsh command called get_latest_release by 1.
Here's my code:
current_version=$(/bin/zsh -i -c get_latest_release)
echo "current version = $current_version" # outputs 'current version = 1'
next=$(($current_version+1)) # gives an error: syntax error: operand expected (error token is "1+1")
echo $next
When I do:
current_version=1
echo "current version = $current_version" # displays current version = 1
next=$(($current_version+1))
echo $next # displays 2
Any idea why I can't get the output incremented by 1?
When I try:
/bin/zsh -i -c get_latest_release | hexdump -C
It strangely outputs the hexdump of the path: file://path_to_current_script.1.
So I just copied the get_latest_release() function to my script and it's now working! I really don't know why it's not working when the command is called with /bin/zsh.
I am running run_lm_finetuning on colab, to fine tune CamemBERT on custom vocabulary.
I am using the following parameters:
!python run_lm_finetuning.py \
--output_dir Skander/ \
--model_type camembert\
--model_name_or_path camembert-base \
--do_train \
--train_data_file="Text.txt" \
--line_by_line\
--mlm\
--per_gpu_train_batch_size=32 \
--num_train_epochs=3 \
However, I am getting the following error:
tcmalloc: large alloc 1264730112 bytes == 0xe87fe000 # 0x7f9828a8f1e7 0x5ad4cb 0x4bb356 0x5bd993 0x50a8af 0x50c5b9 0x508245 0x509642 0x595311 0x54a6ff 0x551b81 0x5aa6ec 0x50abb3 0x50d390 0x508245 0x50a080 0x50aa7d 0x50d390 0x508245 0x50a080 0x50aa7d 0x50c5b9 0x508245 0x50b403 0x635222 0x6352d7 0x638a8f 0x639631 0x4b0f40 0x7f982868cb97 0x5b2fda
^C
Anyone has an idea about this error?
Here, is my configuration:
Table Name: MY_TABLE
Primary partition key method (String)
Primary sort key path (String)
and I would like to query agains two fields:
1. method (Primary partition key): GET
2. path (Primary sort key): /greet/v1/hello
I have used '#pathKey' because 'path' is a reserved keyword. (Similar for #methodKey)
aws dynamodb query --table-name MY_TABLE \
--key-condition-expression '#pathKey=:path1 AND #methodKey=:method1' \
--expression-attribute-names '{"#pathKey":"path"}' \
--expression-attribute-names '{"#methodKey":"method"}' \
--expression-attribute-values '{":method1":{"S":"GET"}}' \
--expression-attribute-values '{":path1":{"S":"/greet/v1/hello"}}'
But while doing so, I am getting the below error:
An error occurred (ValidationException) when calling the Query operation: Invalid KeyConditionExpression: An expression attribute name used in the document path is not defined; attribute name: #pathKey
Please note that, I don't want to use an external JSON file to pass parameters and needs to run on command line.
You should provide all expression attribute names under the same CLI argument (also true for the values).
What happened is that --expression-attribute-names '{"#methodKey":"method"}' override the one before. Hence, the error is regarding missing #pathKey.
It should work for you this way:
aws dynamodb query --table-name MY_TABLE \
--key-condition-expression '#pathKey=:path1 AND #methodKey=:method1' \
--expression-attribute-names '{"#pathKey":"path", "#methodKey":"method"}' \
--expression-attribute-values '{":path1":{"S":"/greet/v1/hello"}, ":method1":{"S":"GET"}}'
I am working on a simple R package to submit hashes for trusted timestamping and to get timestamp info back through Origin Timestamps. I manage to get the information, but I do not manage to POST it OpenTimestamp post hash.
I am using the http package in R. My package ROriginStamp is on github, and the function which I do not get to work is store_hash_info().
Whenever I execute it, I get:
> store_hash(hash = "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e")
Error in store_hash(hash = "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e") :
Bad Request (HTTP 400).
3.
stop(http_condition(x, "error", task = task, call = call))
2.
httr::stop_for_status(result$response) at store_hash.R#29
1.
store_hash(hash = "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e")
>
The function is defined as follow:
store_hash <- function(
hash,
error_on_fail = TRUE,
information = NULL
) {
result <- new_OriginStampResponse()
##
url <- paste0("https://api.originstamp.org/api/", hash)
request_body_json <- jsonlite::toJSON( information, auto_unbox = TRUE )
result$response <- httr::POST(
url,
httr::add_headers(
Authorization = get_option("api_key"),
body = request_body_json
),
httr::content_type_json()
)
if (error_on_fail) {
httr::stop_for_status(result$response)
}
##
try(
{
result$content <- httr::content(
x = result$response,
as = "text"
)
result$content <- jsonlite::fromJSON( result$content )
},
silent = TRUE
)
##
return(result)
}
The function get_option("api_key") just returns my api key.
Any suggestions what I am doing wrong?
Edits
Thanks to Thomas Hepp, Here is a curl command which does work:
curl 'https://api.originstamp.org/api/ff55d7bc3fe6cb2958e4bdda3d4a4a8e528fb67d9194991e9539d97a55cda2a3' \
-H 'authorization: YOUR API KEY' \
-H 'content-type: application/json' \
-H 'accept: application/json' \
-H 'user-agent: OriginStamp cURL Test' \
--data-binary '{"url":null,"email":null,"comment":"this is a test","submit_ops":["multi_seed"]}'
I’m not familiar with R. But, it’s possible to timestamp a file using opentimestamps.org, by posting a hash of the file to one of their calendar servers, using the following methodology. There is no need for an API key, and this procedure can be used to prove the existence of the file at a point in time, via a reference to a value stored in the OP_RETURN field of a bitcoin transaction, in a block in the bitcoin blockchain.
As an example, first, create a test file:
$ echo -n 'this is a test... this is only a test...' > file.txt
Now, take a sha256 hash of the file:
$ sha256sum file.txt
This produces:
c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca
Now, to create a timestamp of the file, post the raw bytes of the hash to one of the calendar servers (e.g. https://a.pool.opentimestamps.org/). This can be done using curl, like so:
$ echo -n 'c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca' | xxd -r -p | curl -X POST --data-binary - https://a.pool.opentimestamps.org/digest > out.ots
[Optional: If you don’t want to disclose the hash of the file that you are timestamping to Opentimestamps, you can add a random salt to the file hash, then do sha256(original file hash + salt) and post the result of this.]
The response from the above request is redirected to a file out.ots. To get the status of the timestamp, we need to parse the raw bytes of out.ots.
First, view the raw bytes of the file using a hex editor, or xxd:
$ xxd out.ots
00000000: f010 95ee b35a b002 5b8b 5e76 3522 6970 .....Z..[.^v5"ip
00000010: 886c 08f1 0462 be3e 32f0 081a ff1c ae94 .l...b.>2.......
00000020: 4f00 4600 83df e30d 2ef9 0c8e 2e2d 6874 O.F..........-ht
00000030: 7470 733a 2f2f 616c 6963 652e 6274 632e tps://alice.btc.
00000040: 6361 6c65 6e64 6172 2e6f 7065 6e74 696d calendar.opentim
00000050: 6573 7461 6d70 732e 6f72 67 estamps.org
Some of the bytes represent instructions, as follows:
f0 xx: append xx bytes
f1 xx: prepend xx bytes
80: sha256 hash
00: stop
Start with the hash that we timestamped:
c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca
then, proceed by parsing the response of the POST request. The first two bytes are f0 10. This means append the next 16 bytes (10 in hex is 16 in decimal). This produces:
c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca95eeb35ab0025b8b5e7635226970886c
Continuing parsing the POST response, the next byte is 80. This means take the sha256 hash of the above.
echo -n ‘c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca95eeb35ab0025b8b5e7635226970886c’ | xxd -p -r | sha256sum
produces:
f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef35090
Continuing, we have f1 04. This means prepend the next 4 bytes to the above. This produces:
62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef35090
Next, we have f0 08. Append the next 8 bytes. This produces:
62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef350901aff1cae944f0046
Finally, we have 00. This means stop. At this point, skip the next 10 bytes, then extract starting from this point to get the URL that we’ll need to get the status of the timestamp:
https://alice.btc.calendar.opentimestamps.org
then, concatenate ‘/timestamp/’ followed by the result above:
https://alice.btc.calendar.opentimestamps.org/timestamp/62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef350901aff1cae944f0046
The status of the timestamp can be accessed by making a GET request to the above URL:
curl https://alice.btc.calendar.opentimestamps.org/timestamp/62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef350901aff1cae944f0046
returns:
Pending confirmation in Bitcoin blockchain
If you wait a few hours, the confirmation will be written to the bitcoin blockchain, and the above GET request will return a much longer proof like the one above, eventually chaining-up to a value that is written to the OP_RETURN field of a bitcoin transaction, in a block in the bitcoin blockchain. By saving this proof, you can verify the existence of the file at the point in time that the block was written to the blockchain, without the need to query the Opentimestamps servers.
The following python script automates the above procedure:
import hashlib
import requests
filehash=bytes.fromhex('c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca')
server='https://a.pool.opentimestamps.org/digest'
print('posting ' + filehash.hex() + ' to ' + server)
response=requests.post(url=server, data=filehash)
bytearray=response.content
print('saving response to ./out.ots')
f=open('./out.ots', 'wb')
f.write(bytearray)
f.close()
print('analysing response')
i=0
ptr=0x00
result=filehash
while(True):
print(i)
print('ptr:', hex(ptr))
nextinstruction=bytearray[ptr]
if(nextinstruction==0xf0):
#append
ptr+=1
numberofbytes=bytearray[ptr]
ptr+=1
bytesegment=bytearray[ptr:ptr+numberofbytes]
print('append ', bytesegment.hex())
result=result+bytesegment
ptr+=numberofbytes
elif(nextinstruction==0xf1):
#prepend
ptr+=1
numberofbytes=bytearray[ptr]
ptr+=1
bytesegment=bytearray[ptr:ptr+numberofbytes]
print('prepend ', bytesegment.hex())
result=bytesegment+result
ptr+=numberofbytes
elif(nextinstruction==0x08):
#sha256
print('sha256')
result=hashlib.sha256(result).digest()
ptr+=1
elif(nextinstruction==0xff):
#fork
print('fork')
ptr+=1
elif(nextinstruction==0x00):
#stop
print('stop')
ptr+=11
url=bytearray[ptr:].decode()
url=url + '/timestamp/' + result.hex()
print('url: ', url)
else:
print('invalid ots file format')
quit()
print('result:', result.hex())
print('-----')
i+=1
if(nextinstruction==0x00): break
print('to get status of timestamp, make a GET request to ' + url)
print('GET ' + url)
response=requests.get(url)
print(response.text)